Merge mozilla-central to autoland a=merge on a CLOSED TREE
authorCoroiu Cristina <ccoroiu@mozilla.com>
Sun, 17 Jun 2018 12:50:17 +0300
changeset 479535 de04d47566e1cf680adddb00737c41e510ed7c63
parent 479534 5402f880b4276aa215824b0ae60e9f195b62c9a2 (current diff)
parent 479529 c40cc0a89bc70511751d17ed0cdd569a74abac88 (diff)
child 479536 1bc876a7147b79d262e27e74edd7a7cf93070c45
push id1757
push userffxbld-merge
push dateFri, 24 Aug 2018 17:02:43 +0000
treeherdermozilla-release@736023aebdb1 [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
--- a/dom/base/TabGroup.cpp
+++ b/dom/base/TabGroup.cpp
@@ -4,38 +4,46 @@
  * 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/. */
 
 #include "mozilla/dom/TabGroup.h"
 
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/DocGroup.h"
+#include "mozilla/dom/TimeoutManager.h"
 #include "mozilla/AbstractThread.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/ThrottledEventQueue.h"
 #include "nsIDocShell.h"
 #include "nsIEffectiveTLDService.h"
 #include "nsIURI.h"
 
 namespace mozilla {
 namespace dom {
 
 static StaticRefPtr<TabGroup> sChromeTabGroup;
 
+LinkedList<TabGroup>* TabGroup::sTabGroups = nullptr;
+
 TabGroup::TabGroup(bool aIsChrome)
  : mLastWindowLeft(false)
  , mThrottledQueuesInitialized(false)
  , mNumOfIndexedDBTransactions(0)
  , mNumOfIndexedDBDatabases(0)
  , mIsChrome(aIsChrome)
  , mForegroundCount(0)
 {
+  if (!sTabGroups) {
+    sTabGroups = new LinkedList<TabGroup>();
+  }
+  sTabGroups->insertBack(this);
+
   CreateEventTargets(/* aNeedValidation = */ !aIsChrome);
 
   // Do not throttle runnables from chrome windows.  In theory we should
   // not have abuse issues from these windows and many browser chrome
   // tests have races that fail if we do throttle chrome runnables.
   if (aIsChrome) {
     MOZ_ASSERT(!sChromeTabGroup);
     return;
@@ -49,16 +57,25 @@ TabGroup::TabGroup(bool aIsChrome)
   }
 }
 
 TabGroup::~TabGroup()
 {
   MOZ_ASSERT(mDocGroups.IsEmpty());
   MOZ_ASSERT(mWindows.IsEmpty());
   MOZ_RELEASE_ASSERT(mLastWindowLeft || mIsChrome);
+
+  LinkedListElement<TabGroup>* listElement =
+    static_cast<LinkedListElement<TabGroup>*>(this);
+  listElement->remove();
+
+  if (sTabGroups->isEmpty()) {
+    delete sTabGroups;
+    sTabGroups = nullptr;
+  }
 }
 
 void
 TabGroup::EnsureThrottledEventQueues()
 {
   if (mThrottledQueuesInitialized) {
     return;
   }
@@ -318,10 +335,42 @@ TabGroup::Count(bool aActiveOnly) const
     if (iter.Get()->mDocGroup->IsActive()) {
       ++count;
     }
   }
 
   return count;
 }
 
+/*static*/ bool
+TabGroup::HasOnlyThrottableTabs()
+{
+  if (!sTabGroups) {
+    return false;
+  }
+
+  for (TabGroup* tabGroup = sTabGroups->getFirst(); tabGroup;
+       tabGroup =
+         static_cast<LinkedListElement<TabGroup>*>(tabGroup)->getNext()) {
+    for (auto iter = tabGroup->Iter(); !iter.Done(); iter.Next()) {
+      DocGroup* docGroup = iter.Get()->mDocGroup;
+      for (auto* documentInDocGroup : *docGroup) {
+        if (documentInDocGroup->IsCurrentActiveDocument()) {
+          nsPIDOMWindowInner* win =
+            documentInDocGroup->GetInnerWindow();
+          if (win && win->IsCurrentInnerWindow()) {
+            nsPIDOMWindowOuter* outer = win->GetOuterWindow();
+            if (outer) {
+              TimeoutManager& tm = win->TimeoutManager();
+              if (!tm.BudgetThrottlingEnabled(outer->IsBackground())) {
+                return false;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  return true;
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/TabGroup.h
+++ b/dom/base/TabGroup.h
@@ -41,17 +41,18 @@ class TabChild;
 // more detail, a DocGroup is actually a collection of documents, and a
 // TabGroup is a collection of DocGroups. A TabGroup typically will contain
 // (through its DocGroups) the documents from one or more tabs related by
 // window.opener. A DocGroup is a member of exactly one TabGroup.
 
 class DocGroup;
 class TabChild;
 
-class TabGroup final : public SchedulerGroup
+class TabGroup final : public SchedulerGroup,
+                       public LinkedListElement<TabGroup>
 {
 private:
   class HashEntry : public nsCStringHashKey
   {
   public:
     // NOTE: Weak reference. The DocGroup destructor removes itself from its
     // owning TabGroup.
     DocGroup* mDocGroup;
@@ -141,16 +142,26 @@ public:
     return mNumOfIndexedDBTransactions;
   }
 
   Atomic<uint32_t>& IndexedDBDatabaseCounter()
   {
     return mNumOfIndexedDBDatabases;
   }
 
+  static LinkedList<TabGroup>* GetTabGroupList()
+  {
+    return sTabGroups;
+  }
+
+  // This returns true if all the window objects in all the TabGroups are
+  // either inactive (for example in bfcache) or are in background tabs which
+  // can be throttled.
+  static bool HasOnlyThrottableTabs();
+
 private:
   virtual AbstractThread*
   AbstractMainThreadForImpl(TaskCategory aCategory) override;
 
   TabGroup* AsTabGroup() override { return this; }
 
   void EnsureThrottledEventQueues();
 
@@ -162,14 +173,16 @@ private:
   Atomic<uint32_t> mNumOfIndexedDBTransactions;
   Atomic<uint32_t> mNumOfIndexedDBDatabases;
   const bool mIsChrome;
 
   // Main thread only
   DocGroupMap mDocGroups;
   nsTArray<nsPIDOMWindowOuter*> mWindows;
   uint32_t mForegroundCount;
+
+  static LinkedList<TabGroup>* sTabGroups;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // defined(TabGroup_h)
--- a/dom/base/TimeoutManager.h
+++ b/dom/base/TimeoutManager.h
@@ -106,16 +106,18 @@ public:
   }
 
   void BeginSyncOperation();
   void EndSyncOperation();
 
   nsIEventTarget*
   EventTarget();
 
+  bool BudgetThrottlingEnabled(bool aIsBackground) const;
+
   static const uint32_t InvalidFiringId;
 
 private:
   void MaybeStartThrottleTimeout();
 
   // Return true if |aTimeout| needs to be reinserted into the timeout list.
   bool RescheduleTimeout(mozilla::dom::Timeout* aTimeout,
                          const TimeStamp& aLastCallbackTime,
@@ -144,18 +146,16 @@ private:
                          const TimeStamp& aNow = TimeStamp::Now());
 
   void RecordExecution(Timeout* aRunningTimeout,
                        Timeout* aTimeout);
 
   void UpdateBudget(const TimeStamp& aNow,
                     const TimeDuration& aDuration = TimeDuration());
 
-  bool BudgetThrottlingEnabled(bool aIsBackground) const;
-
 private:
   struct Timeouts {
     explicit Timeouts(const TimeoutManager& aManager)
       : mManager(aManager)
     {
     }
 
     // Insert aTimeout into the list, before all timeouts that would
--- a/dom/smil/nsSMILKeySpline.h
+++ b/dom/smil/nsSMILKeySpline.h
@@ -11,26 +11,37 @@
 #include "mozilla/PodOperations.h"
 
 /**
  * Utility class to provide scaling defined in a keySplines element.
  */
 class nsSMILKeySpline
 {
 public:
-  nsSMILKeySpline() { /* caller must call Init later */ }
+  nsSMILKeySpline()
+    : mX1(0)
+    , mY1(0)
+    , mX2(0)
+    , mY2(0)
+  { 
+    /* caller must call Init later */\
+  }
 
   /**
    * Creates a new key spline control point description.
    *
    * aX1, etc. are the x1, y1, x2, y2 cubic Bezier control points as defined by
    * SMILANIM 3.2.3. They must each be in the range 0.0 <= x <= 1.0
    */
   nsSMILKeySpline(double aX1, double aY1,
                   double aX2, double aY2)
+    : mX1(0)
+    , mY1(0)
+    , mX2(0)
+    , mY2(0)
   {
     Init(aX1, aY1, aX2, aY2);
   }
 
   double X1() const { return mX1; }
   double Y1() const { return mY1; }
   double X2() const { return mX2; }
   double Y2() const { return mY2; }
--- a/dom/smil/nsSMILValue.cpp
+++ b/dom/smil/nsSMILValue.cpp
@@ -9,16 +9,17 @@
 #include <string.h>
 
 //----------------------------------------------------------------------
 // Public methods
 
 nsSMILValue::nsSMILValue(const nsISMILType* aType)
   : mType(nsSMILNullType::Singleton())
 {
+  mU.mBool = false;
   if (!aType) {
     NS_ERROR("Trying to construct nsSMILValue with null mType pointer");
     return;
   }
 
   InitAndCheckPostcondition(aType);
 }
 
--- a/dom/svg/DOMSVGPathSegList.h
+++ b/dom/svg/DOMSVGPathSegList.h
@@ -225,17 +225,20 @@ private:
    * store the indexes into the internal SVGPathData of the internal seg data
    * that our DOMSVGPathSeg items wrap (the internal segment data is or varying
    * length, so we can't just use the index of our DOMSVGPathSeg items
    * themselves). The reason that we have this separate struct rather than
    * just storing the internal indexes in the DOMSVGPathSeg items is because we
    * want to create the DOMSVGPathSeg items lazily on demand.
    */
   struct ItemProxy {
-    ItemProxy(){}
+    ItemProxy()
+      : mItem(nullptr)
+      , mInternalDataIndex(0)
+    {}
     ItemProxy(DOMSVGPathSeg *aItem, uint32_t aInternalDataIndex)
       : mItem(aItem)
       , mInternalDataIndex(aInternalDataIndex)
     {}
 
     DOMSVGPathSeg *mItem;
     uint32_t mInternalDataIndex;
   };
--- a/dom/svg/SVGAnimatedNumberList.h
+++ b/dom/svg/SVGAnimatedNumberList.h
@@ -38,17 +38,19 @@ class SVGAnimationElement;
  */
 class SVGAnimatedNumberList
 {
   // friends so that they can get write access to mBaseVal
   friend class DOMSVGNumber;
   friend class DOMSVGNumberList;
 
 public:
-  SVGAnimatedNumberList() {}
+  SVGAnimatedNumberList()
+    : mIsBaseSet(false)
+  {}
 
   /**
    * Because it's so important that mBaseVal and its DOMSVGNumberList wrapper
    * (if any) be kept in sync (see the comment in
    * DOMSVGAnimatedNumberList::InternalBaseValListWillChangeTo), this method
    * returns a const reference. Only our friend classes may get mutable
    * references to mBaseVal.
    */
--- a/dom/svg/SVGGeometryElement.h
+++ b/dom/svg/SVGGeometryElement.h
@@ -107,17 +107,21 @@ public:
 
   /**
    * For use with GetAsSimplePath.
    */
   class SimplePath
   {
   public:
     SimplePath()
-      : mType(NONE)
+      : mX(0.0)
+      , mY(0.0)
+      , mWidthOrX2(0.0)
+      , mHeightOrY2(0.0)
+      , mType(NONE)
     {}
     bool IsPath() const {
       return mType != NONE;
     }
     void SetRect(Float x, Float y, Float width, Float height) {
       mX = x;
       mY = y;
       mWidthOrX2 = width;
--- a/dom/svg/SVGLength.h
+++ b/dom/svg/SVGLength.h
@@ -28,20 +28,18 @@ namespace mozilla {
  *
  * The DOM wrapper class for this class is DOMSVGLength.
  */
 class SVGLength
 {
 public:
 
   SVGLength()
-#ifdef DEBUG
     : mValue(0.0f)
     , mUnit(dom::SVGLengthBinding::SVG_LENGTHTYPE_UNKNOWN) // caught by IsValid()
-#endif
   {}
 
   SVGLength(float aValue, uint8_t aUnit)
     : mValue(aValue)
     , mUnit(aUnit)
   {
     NS_ASSERTION(IsValid(), "Constructed an invalid length");
   }
--- a/dom/svg/SVGLengthList.h
+++ b/dom/svg/SVGLengthList.h
@@ -306,16 +306,18 @@ private:
  * numeric_limits<float>::quiet_NaN().
  */
 class MOZ_STACK_CLASS SVGUserUnitList
 {
 public:
 
   SVGUserUnitList()
     : mList(nullptr)
+    , mElement(nullptr)
+    , mAxis(0)
   {}
 
   void Init(const SVGLengthList *aList, nsSVGElement *aElement, uint8_t aAxis) {
     mList = aList;
     mElement = aElement;
     mAxis = aAxis;
   }
 
--- a/dom/svg/SVGMotionSMILType.cpp
+++ b/dom/svg/SVGMotionSMILType.cpp
@@ -59,17 +59,20 @@ struct PathPointParams {  // Point along
  * from a path (e.g. when accumulating a repeated animation) will generally
  * take you to an arbitrary point *off* of the path.
  */
 struct MotionSegment
 {
   // Default constructor just locks us into being a Translation, and leaves
   // other fields uninitialized (since client is presumably about to set them)
   MotionSegment()
-    : mSegmentType(eSegmentType_Translation)
+    : mRotateType(eRotateType_Auto),
+      mRotateAngle(0.0),
+      mSegmentType(eSegmentType_Translation),
+      mU{}
   { }
 
   // Constructor for a translation
   MotionSegment(float aX, float aY, float aRotateAngle)
     : mRotateType(eRotateType_Explicit), mRotateAngle(aRotateAngle),
       mSegmentType(eSegmentType_Translation)
   {
     mU.mTranslationParams.mX = aX;
--- a/dom/svg/nsSVGViewBox.h
+++ b/dom/svg/nsSVGViewBox.h
@@ -27,17 +27,23 @@ class SVGAnimationElement;
 } // namespace mozilla
 
 struct nsSVGViewBoxRect
 {
   float x, y;
   float width, height;
   bool none;
 
-  nsSVGViewBoxRect() : none(true) {}
+  nsSVGViewBoxRect()
+    : x(0.0)
+    , y(0.0)
+    , width(0.0)
+    , height(0.0)
+    , none(true)
+  {}
   nsSVGViewBoxRect(float aX, float aY, float aWidth, float aHeight) :
     x(aX), y(aY), width(aWidth), height(aHeight), none(false) {}
   nsSVGViewBoxRect(const nsSVGViewBoxRect& rhs) :
     x(rhs.x), y(rhs.y), width(rhs.width), height(rhs.height), none(rhs.none) {}
   bool operator==(const nsSVGViewBoxRect& aOther) const;
 
   static nsresult FromString(const nsAString& aStr, nsSVGViewBoxRect *aViewBox);
 };
--- a/js/src/builtin/ReflectParse.cpp
+++ b/js/src/builtin/ReflectParse.cpp
@@ -277,18 +277,17 @@ class NodeBuilder
                 return false;
 
             if (funv.isNullOrUndefined()) {
                 callbacks[i].setNull();
                 continue;
             }
 
             if (!funv.isObject() || !funv.toObject().is<JSFunction>()) {
-                ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_NOT_FUNCTION,
-                                      JSDVG_SEARCH_STACK, funv, nullptr, nullptr, nullptr);
+                ReportValueError(cx, JSMSG_NOT_FUNCTION, JSDVG_SEARCH_STACK, funv, nullptr);
                 return false;
             }
 
             callbacks[i].set(funv);
         }
 
         return true;
     }
@@ -3357,19 +3356,18 @@ reflect_parse(JSContext* cx, uint32_t ar
     bool loc = true;
     RootedObject builder(cx);
     ParseGoal target = ParseGoal::Script;
 
     RootedValue arg(cx, args.get(1));
 
     if (!arg.isNullOrUndefined()) {
         if (!arg.isObject()) {
-            ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                                  JSDVG_SEARCH_STACK, arg, nullptr,
-                                  "not an object", nullptr);
+            ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, arg, nullptr,
+                             "not an object");
             return false;
         }
 
         RootedObject config(cx, &arg.toObject());
 
         RootedValue prop(cx);
 
         /* config.loc */
@@ -3409,33 +3407,32 @@ reflect_parse(JSContext* cx, uint32_t ar
         /* config.builder */
         RootedId builderId(cx, NameToId(cx->names().builder));
         RootedValue nullVal(cx, NullValue());
         if (!GetPropertyDefault(cx, config, builderId, nullVal, &prop))
             return false;
 
         if (!prop.isNullOrUndefined()) {
             if (!prop.isObject()) {
-                ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                                      JSDVG_SEARCH_STACK, prop, nullptr,
-                                      "not an object", nullptr);
+                ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, prop, nullptr,
+                                 "not an object");
                 return false;
             }
             builder = &prop.toObject();
         }
 
         /* config.target */
         RootedId targetId(cx, NameToId(cx->names().target));
         RootedValue scriptVal(cx, StringValue(cx->names().script));
         if (!GetPropertyDefault(cx, config, targetId, scriptVal, &prop))
             return false;
 
         if (!prop.isString()) {
-            ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK,
-                                  prop, nullptr, "not 'script' or 'module'", nullptr);
+            ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, prop, nullptr,
+                             "not 'script' or 'module'");
             return false;
         }
 
         RootedString stringProp(cx, prop.toString());
         bool isScript = false;
         bool isModule = false;
         if (!EqualStrings(cx, stringProp, cx->names().script, &isScript))
             return false;
--- a/js/src/builtin/Stream.cpp
+++ b/js/src/builtin/Stream.cpp
@@ -265,27 +265,25 @@ static MOZ_MUST_USE JSObject*
 PromiseRejectedWithPendingError(JSContext* cx) {
     // Not much we can do about uncatchable exceptions, just bail.
     RootedValue exn(cx);
     if (!GetAndClearException(cx, &exn))
         return nullptr;
     return PromiseObject::unforgeableReject(cx, exn);
 }
 
-static bool
-ReportArgTypeError(JSContext* cx, const char* funName, const char* expectedType,
-                   HandleValue arg)
+static void
+ReportArgTypeError(JSContext* cx, const char* funName, const char* expectedType, HandleValue arg)
 {
     UniqueChars bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, arg, nullptr);
     if (!bytes)
-        return false;
-
-    return JS_ReportErrorFlagsAndNumberLatin1(cx, JSREPORT_ERROR, GetErrorMessage,
-                                              nullptr, JSMSG_NOT_EXPECTED_TYPE,
-                                              funName, expectedType, bytes.get());
+        return;
+
+    JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE, funName,
+                               expectedType, bytes.get());
 }
 
 static MOZ_MUST_USE bool
 RejectWithPendingError(JSContext* cx, Handle<PromiseObject*> promise) {
     // Not much we can do about uncatchable exceptions, just bail.
     RootedValue exn(cx);
     if (!GetAndClearException(cx, &exn))
         return false;
@@ -302,18 +300,18 @@ ReturnPromiseRejectedWithPendingError(JS
     args.rval().setObject(*promise);
     return true;
 }
 
 static MOZ_MUST_USE bool
 RejectNonGenericMethod(JSContext* cx, const CallArgs& args,
                        const char* className, const char* methodName)
 {
-    ReportValueError3(cx, JSMSG_INCOMPATIBLE_PROTO, JSDVG_SEARCH_STACK, args.thisv(),
-                      nullptr, className, methodName);
+    ReportValueError(cx, JSMSG_INCOMPATIBLE_PROTO, JSDVG_SEARCH_STACK, args.thisv(),
+                     nullptr, className, methodName);
 
     return ReturnPromiseRejectedWithPendingError(cx, args);
 }
 
 inline static MOZ_MUST_USE NativeObject*
 SetNewList(JSContext* cx, HandleNativeObject container, uint32_t slot)
 {
     NativeObject* list = NewList(cx);
@@ -798,18 +796,18 @@ ReadableStream_locked(JSContext* cx, uns
 // Streams spec, 3.2.4.2. cancel ( reason )
 static MOZ_MUST_USE bool
 ReadableStream_cancel(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     // Step 1: If ! IsReadableStream(this) is false, return a promise rejected
     //         with a TypeError exception.
     if (!Is<ReadableStream>(args.thisv())) {
-        ReportValueError3(cx, JSMSG_INCOMPATIBLE_PROTO, JSDVG_SEARCH_STACK, args.thisv(),
-                          nullptr, "cancel", "");
+        ReportValueError(cx, JSMSG_INCOMPATIBLE_PROTO, JSDVG_SEARCH_STACK, args.thisv(),
+                         nullptr, "cancel", "");
         return ReturnPromiseRejectedWithPendingError(cx, args);
     }
 
     Rooted<ReadableStream*> stream(cx, &args.thisv().toObject().as<ReadableStream>());
 
     // Step 2: If ! IsReadableStreamLocked(this) is true, return a promise
     //         rejected with a TypeError exception.
     if (stream->locked()) {
--- a/js/src/builtin/Symbol.cpp
+++ b/js/src/builtin/Symbol.cpp
@@ -145,18 +145,18 @@ SymbolObject::for_(JSContext* cx, unsign
 bool
 SymbolObject::keyFor(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     // step 1
     HandleValue arg = args.get(0);
     if (!arg.isSymbol()) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK,
-                              arg, nullptr, "not a symbol", nullptr);
+        ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, arg, nullptr,
+                         "not a symbol");
         return false;
     }
 
     // step 2
     if (arg.toSymbol()->code() == JS::SymbolCode::InSymbolRegistry) {
 #ifdef DEBUG
         RootedString desc(cx, arg.toSymbol()->description());
         MOZ_ASSERT(Symbol::for_(cx, desc) == arg.toSymbol());
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -1299,32 +1299,30 @@ SaveStack(JSContext* cx, unsigned argc, 
     CallArgs args = CallArgsFromVp(argc, vp);
 
     JS::StackCapture capture((JS::AllFrames()));
     if (args.length() >= 1) {
         double maxDouble;
         if (!ToNumber(cx, args[0], &maxDouble))
             return false;
         if (mozilla::IsNaN(maxDouble) || maxDouble < 0 || maxDouble > UINT32_MAX) {
-            ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                                  JSDVG_SEARCH_STACK, args[0], nullptr,
-                                  "not a valid maximum frame count", NULL);
+            ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[0], nullptr,
+                             "not a valid maximum frame count");
             return false;
         }
         uint32_t max = uint32_t(maxDouble);
         if (max > 0)
             capture = JS::StackCapture(JS::MaxFrames(max));
     }
 
     RootedObject compartmentObject(cx);
     if (args.length() >= 2) {
         if (!args[1].isObject()) {
-            ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                                  JSDVG_SEARCH_STACK, args[0], nullptr,
-                                  "not an object", NULL);
+            ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[0], nullptr,
+                             "not an object");
             return false;
         }
         compartmentObject = UncheckedUnwrap(&args[1].toObject());
         if (!compartmentObject)
             return false;
     }
 
     RootedObject stack(cx);
@@ -3588,26 +3586,24 @@ FindPath(JSContext* cx, unsigned argc, V
                                   "findPath", "1", "");
         return false;
     }
 
     // We don't ToString non-objects given as 'start' or 'target', because this
     // test is all about object identity, and ToString doesn't preserve that.
     // Non-GCThing endpoints don't make much sense.
     if (!args[0].isObject() && !args[0].isString() && !args[0].isSymbol()) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                              JSDVG_SEARCH_STACK, args[0], nullptr,
-                              "not an object, string, or symbol", NULL);
+        ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[0], nullptr,
+                         "not an object, string, or symbol");
         return false;
     }
 
     if (!args[1].isObject() && !args[1].isString() && !args[1].isSymbol()) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                              JSDVG_SEARCH_STACK, args[0], nullptr,
-                              "not an object, string, or symbol", NULL);
+        ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[0], nullptr,
+                         "not an object, string, or symbol");
         return false;
     }
 
     Rooted<GCVector<Value>> nodes(cx, GCVector<Value>(cx));
     Vector<heaptools::EdgeName> edges(cx);
 
     {
         // We can't tolerate the GC moving things around while we're searching
@@ -3693,53 +3689,49 @@ ShortestPaths(JSContext* cx, unsigned ar
     CallArgs args = CallArgsFromVp(argc, vp);
     if (!args.requireAtLeast(cx, "shortestPaths", 3))
         return false;
 
     // We don't ToString non-objects given as 'start' or 'target', because this
     // test is all about object identity, and ToString doesn't preserve that.
     // Non-GCThing endpoints don't make much sense.
     if (!args[0].isObject() && !args[0].isString() && !args[0].isSymbol()) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                              JSDVG_SEARCH_STACK, args[0], nullptr,
-                              "not an object, string, or symbol", nullptr);
+        ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[0], nullptr,
+                         "not an object, string, or symbol");
         return false;
     }
 
     if (!args[1].isObject() || !args[1].toObject().is<ArrayObject>()) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                              JSDVG_SEARCH_STACK, args[1], nullptr,
-                              "not an array object", nullptr);
+        ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[1], nullptr,
+                         "not an array object");
         return false;
     }
 
     RootedArrayObject objs(cx, &args[1].toObject().as<ArrayObject>());
     size_t length = objs->getDenseInitializedLength();
     if (length == 0) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                              JSDVG_SEARCH_STACK, args[1], nullptr,
-                              "not a dense array object with one or more elements", nullptr);
+        ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[1], nullptr,
+                         "not a dense array object with one or more elements");
         return false;
     }
 
     for (size_t i = 0; i < length; i++) {
         RootedValue el(cx, objs->getDenseElement(i));
         if (!el.isObject() && !el.isString() && !el.isSymbol()) {
             JS_ReportErrorASCII(cx, "Each target must be an object, string, or symbol");
             return false;
         }
     }
 
     int32_t maxNumPaths;
     if (!JS::ToInt32(cx, args[2], &maxNumPaths))
         return false;
     if (maxNumPaths <= 0) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                              JSDVG_SEARCH_STACK, args[2], nullptr,
-                              "not greater than 0", nullptr);
+        ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[2], nullptr,
+                         "not greater than 0");
         return false;
     }
 
     // We accumulate the results into a GC-stable form, due to the fact that the
     // JS::ubi::ShortestPaths lifetime (when operating on the live heap graph)
     // is bounded within an AutoCheckCannotGC.
     Rooted<GCVector<GCVector<GCVector<Value>>>> values(cx, GCVector<GCVector<GCVector<Value>>>(cx));
     Vector<Vector<Vector<JS::ubi::EdgeName>>> names(cx);
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -92,20 +92,18 @@ GetDeflatedUTF8StringLength(JSContext* m
     }
     return nbytes;
 
   bad_surrogate:
     if (maybecx) {
         js::gc::AutoSuppressGC suppress(maybecx);
         char buffer[10];
         SprintfLiteral(buffer, "0x%x", c);
-        JS_ReportErrorFlagsAndNumberASCII(maybecx, JSREPORT_ERROR,
-                                          GetErrorMessage,
-                                          nullptr, JSMSG_BAD_SURROGATE_CHAR,
-                                          buffer);
+        JS_ReportErrorNumberASCII(maybecx, GetErrorMessage, nullptr, JSMSG_BAD_SURROGATE_CHAR,
+                                  buffer);
     }
     return (size_t) -1;
 }
 
 template size_t
 GetDeflatedUTF8StringLength(JSContext* maybecx, const Latin1Char* chars,
                             size_t nchars);
 
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -7088,17 +7088,17 @@ JSErrorNotes::copy(JSContext* cx)
 {
     auto copiedNotes = MakeUnique<JSErrorNotes>();
     if (!copiedNotes) {
         ReportOutOfMemory(cx);
         return nullptr;
     }
 
     for (auto&& note : *this) {
-        js::UniquePtr<JSErrorNotes::Note> copied(CopyErrorNote(cx, note.get()));
+        UniquePtr<JSErrorNotes::Note> copied = CopyErrorNote(cx, note.get());
         if (!copied)
             return nullptr;
 
         if (!copiedNotes->notes_.append(std::move(copied)))
             return nullptr;
     }
 
     return copiedNotes;
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -491,23 +491,16 @@ static const uint8_t JSPROP_INTERNAL_USE
 
 /* native that can be called as a ctor */
 static const unsigned JSFUN_CONSTRUCTOR =     0x400;
 
 /* | of all the JSFUN_* flags */
 static const unsigned JSFUN_FLAGS_MASK =      0x400;
 
 /*
- * If set, will allow redefining a non-configurable property, but only on a
- * non-DOM global.  This is a temporary hack that will need to go away in bug
- * 1105518.
- */
-static const unsigned JSPROP_REDEFINE_NONCONFIGURABLE = 0x1000;
-
-/*
  * Resolve hooks and enumerate hooks must pass this flag when calling
  * JS_Define* APIs to reify lazily-defined properties.
  *
  * JSPROP_RESOLVING is used only with property-defining APIs. It tells the
  * engine to skip the resolve hook when performing the lookup at the beginning
  * of property definition. This keeps the resolve hook from accidentally
  * triggering itself: unchecked recursion.
  *
@@ -2107,17 +2100,16 @@ class WrappedPtrOperations<JS::PropertyD
     void assertValid() const {
 #ifdef DEBUG
         MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE | JSPROP_IGNORE_ENUMERATE |
                                      JSPROP_PERMANENT | JSPROP_IGNORE_PERMANENT |
                                      JSPROP_READONLY | JSPROP_IGNORE_READONLY |
                                      JSPROP_IGNORE_VALUE |
                                      JSPROP_GETTER |
                                      JSPROP_SETTER |
-                                     JSPROP_REDEFINE_NONCONFIGURABLE |
                                      JSPROP_RESOLVING |
                                      SHADOWABLE)) == 0);
         MOZ_ASSERT(!hasAll(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE));
         MOZ_ASSERT(!hasAll(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT));
         if (isAccessorDescriptor()) {
             MOZ_ASSERT(!has(JSPROP_READONLY));
             MOZ_ASSERT(!has(JSPROP_IGNORE_READONLY));
             MOZ_ASSERT(!has(JSPROP_IGNORE_VALUE));
@@ -2129,29 +2121,27 @@ class WrappedPtrOperations<JS::PropertyD
             MOZ_ASSERT(!hasAll(JSPROP_IGNORE_READONLY | JSPROP_READONLY));
             MOZ_ASSERT_IF(has(JSPROP_IGNORE_VALUE), value().isUndefined());
         }
 
         MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_ENUMERATE));
         MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_PERMANENT));
         MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_READONLY));
         MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_VALUE));
-        MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_REDEFINE_NONCONFIGURABLE));
 #endif
     }
 
     void assertComplete() const {
 #ifdef DEBUG
         assertValid();
         MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE |
                                      JSPROP_PERMANENT |
                                      JSPROP_READONLY |
                                      JSPROP_GETTER |
                                      JSPROP_SETTER |
-                                     JSPROP_REDEFINE_NONCONFIGURABLE |
                                      JSPROP_RESOLVING |
                                      SHADOWABLE)) == 0);
         MOZ_ASSERT_IF(isAccessorDescriptor(), has(JSPROP_GETTER) && has(JSPROP_SETTER));
 #endif
     }
 
     void assertCompleteIfFound() const {
 #ifdef DEBUG
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -2649,18 +2649,17 @@ date_toJSON(JSContext* cx, unsigned argc
 
     /* Step 4. */
     RootedValue toISO(cx);
     if (!GetProperty(cx, obj, obj, cx->names().toISOString, &toISO))
         return false;
 
     /* Step 5. */
     if (!IsCallable(toISO)) {
-        JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, js::GetErrorMessage, nullptr,
-                                          JSMSG_BAD_TOISOSTRING_PROP);
+        JS_ReportErrorNumberASCII(cx, js::GetErrorMessage, nullptr, JSMSG_BAD_TOISOSTRING_PROP);
         return false;
     }
 
     /* Step 6. */
     return Call(cx, toISO, obj, args.rval());
 }
 
 /* Interface to PRMJTime date struct. */
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -9,25 +9,27 @@
  */
 
 #include "jsexn.h"
 
 #include "mozilla/ScopeExit.h"
 #include "mozilla/Sprintf.h"
 
 #include <string.h>
+#include <utility>
 
 #include "jsapi.h"
 #include "jsnum.h"
 #include "jstypes.h"
 #include "jsutil.h"
 
 #include "gc/FreeOp.h"
 #include "gc/Marking.h"
 #include "js/CharacterEncoding.h"
+#include "js/UniquePtr.h"
 #include "js/Wrapper.h"
 #include "util/StringBuffer.h"
 #include "vm/ErrorObject.h"
 #include "vm/GlobalObject.h"
 #include "vm/JSContext.h"
 #include "vm/JSFunction.h"
 #include "vm/JSObject.h"
 #include "vm/JSScript.h"
@@ -262,17 +264,17 @@ CopyExtraData(JSContext* cx, uint8_t** c
 
 bool
 CopyExtraData(JSContext* cx, uint8_t** cursor, JSErrorNotes::Note* copy, JSErrorNotes::Note* report)
 {
     return true;
 }
 
 template <typename T>
-static T*
+static UniquePtr<T>
 CopyErrorHelper(JSContext* cx, T* report)
 {
     /*
      * We use a single malloc block to make a deep copy of JSErrorReport or
      * JSErrorNotes::Note, except JSErrorNotes linked from JSErrorReport with
      * the following layout:
      *   JSErrorReport or JSErrorNotes::Note
      *   char array with characters for message_
@@ -293,54 +295,51 @@ CopyErrorHelper(JSContext* cx, T* report
      * The mallocSize can not overflow since it represents the sum of the
      * sizes of already allocated objects.
      */
     size_t mallocSize = sizeof(T) + messageSize + filenameSize + ExtraMallocSize(report);
     uint8_t* cursor = cx->pod_calloc<uint8_t>(mallocSize);
     if (!cursor)
         return nullptr;
 
-    T* copy = new (cursor) T();
+    UniquePtr<T> copy(new (cursor) T());
     cursor += sizeof(T);
 
     if (report->message()) {
         copy->initBorrowedMessage((const char*)cursor);
         js_memcpy(cursor, report->message().c_str(), messageSize);
         cursor += messageSize;
     }
 
     if (report->filename) {
         copy->filename = (const char*)cursor;
         js_memcpy(cursor, report->filename, filenameSize);
         cursor += filenameSize;
     }
 
-    if (!CopyExtraData(cx, &cursor, copy, report)) {
-        /* js_delete calls destructor for T and js_free for pod_calloc. */
-        js_delete(copy);
+    if (!CopyExtraData(cx, &cursor, copy.get(), report))
         return nullptr;
-    }
 
-    MOZ_ASSERT(cursor == (uint8_t*)copy + mallocSize);
+    MOZ_ASSERT(cursor == (uint8_t*)copy.get() + mallocSize);
 
     /* Copy non-pointer members. */
     copy->lineno = report->lineno;
     copy->column = report->column;
     copy->errorNumber = report->errorNumber;
 
     return copy;
 }
 
-JSErrorNotes::Note*
+UniquePtr<JSErrorNotes::Note>
 js::CopyErrorNote(JSContext* cx, JSErrorNotes::Note* note)
 {
     return CopyErrorHelper(cx, note);
 }
 
-JSErrorReport*
+UniquePtr<JSErrorReport>
 js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
 {
     return CopyErrorHelper(cx, report);
 }
 
 struct SuppressErrorsGuard
 {
     JSContext* cx;
@@ -681,22 +680,22 @@ js::ErrorToException(JSContext* cx, JSEr
 
     uint32_t lineNumber = reportp->lineno;
     uint32_t columnNumber = reportp->column;
 
     RootedObject stack(cx);
     if (!CaptureStack(cx, &stack))
         return;
 
-    js::ScopedJSFreePtr<JSErrorReport> report(CopyErrorReport(cx, reportp));
+    UniquePtr<JSErrorReport> report = CopyErrorReport(cx, reportp);
     if (!report)
         return;
 
-    RootedObject errObject(cx, ErrorObject::create(cx, exnType, stack, fileName,
-                                                   lineNumber, columnNumber, &report, messageStr));
+    RootedObject errObject(cx, ErrorObject::create(cx, exnType, stack, fileName, lineNumber,
+                                                   columnNumber, std::move(report), messageStr));
     if (!errObject)
         return;
 
     // Throw it.
     cx->setPendingException(ObjectValue(*errObject));
 
     // Flag the error report passed in to indicate an exception was raised.
     reportp->flags |= JSREPORT_EXCEPTION;
@@ -985,17 +984,17 @@ ErrorReport::populateUncaughtExceptionRe
     toStringResult_ = ownedReport.message();
     reportp = &ownedReport;
     return true;
 }
 
 JSObject*
 js::CopyErrorObject(JSContext* cx, Handle<ErrorObject*> err)
 {
-    js::ScopedJSFreePtr<JSErrorReport> copyReport;
+    UniquePtr<JSErrorReport> copyReport;
     if (JSErrorReport* errorReport = err->getErrorReport()) {
         copyReport = CopyErrorReport(cx, errorReport);
         if (!copyReport)
             return nullptr;
     }
 
     RootedString message(cx, err->getMessage());
     if (message && !cx->compartment()->wrap(cx, &message))
@@ -1007,34 +1006,36 @@ js::CopyErrorObject(JSContext* cx, Handl
     if (!cx->compartment()->wrap(cx, &stack))
         return nullptr;
     uint32_t lineNumber = err->lineNumber();
     uint32_t columnNumber = err->columnNumber();
     JSExnType errorType = err->type();
 
     // Create the Error object.
     return ErrorObject::create(cx, errorType, stack, fileName,
-                               lineNumber, columnNumber, &copyReport, message);
+                               lineNumber, columnNumber, std::move(copyReport), message);
 }
 
 JS_PUBLIC_API(bool)
 JS::CreateError(JSContext* cx, JSExnType type, HandleObject stack, HandleString fileName,
                     uint32_t lineNumber, uint32_t columnNumber, JSErrorReport* report,
                     HandleString message, MutableHandleValue rval)
 {
     assertSameCompartment(cx, stack, fileName, message);
     AssertObjectIsSavedFrameOrWrapper(cx, stack);
 
-    js::ScopedJSFreePtr<JSErrorReport> rep;
-    if (report)
+    js::UniquePtr<JSErrorReport> rep;
+    if (report) {
         rep = CopyErrorReport(cx, report);
+        if (!rep)
+            return false;
+    }
 
-    RootedObject obj(cx,
-        js::ErrorObject::create(cx, type, stack, fileName,
-                                lineNumber, columnNumber, &rep, message));
+    JSObject* obj = js::ErrorObject::create(cx, type, stack, fileName, lineNumber, columnNumber,
+                                            std::move(rep), message);
     if (!obj)
         return false;
 
     rval.setObject(*obj);
     return true;
 }
 
 const char*
--- a/js/src/jsexn.h
+++ b/js/src/jsexn.h
@@ -9,25 +9,26 @@
  */
 
 #ifndef jsexn_h
 #define jsexn_h
 
 #include "jsapi.h"
 #include "NamespaceImports.h"
 
+#include "js/UniquePtr.h"
 #include "vm/JSContext.h"
 
 namespace js {
 class ErrorObject;
 
-JSErrorNotes::Note*
+UniquePtr<JSErrorNotes::Note>
 CopyErrorNote(JSContext* cx, JSErrorNotes::Note* note);
 
-JSErrorReport*
+UniquePtr<JSErrorReport>
 CopyErrorReport(JSContext* cx, JSErrorReport* report);
 
 JSString*
 ComputeStackString(JSContext* cx);
 
 /*
  * Given a JSErrorReport, check to see if there is an exception associated with
  * the error number.  If there is, then create an appropriate exception object,
--- a/js/src/vm/CharacterEncoding.cpp
+++ b/js/src/vm/CharacterEncoding.cpp
@@ -225,33 +225,31 @@ JS::Utf8ToOneUcs4Char(const uint8_t* utf
     return ucs4Char;
 }
 
 static void
 ReportInvalidCharacter(JSContext* cx, uint32_t offset)
 {
     char buffer[10];
     SprintfLiteral(buffer, "%u", offset);
-    JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
-                                      JSMSG_MALFORMED_UTF8_CHAR, buffer);
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MALFORMED_UTF8_CHAR, buffer);
 }
 
 static void
 ReportBufferTooSmall(JSContext* cx, uint32_t dummy)
 {
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BUFFER_TOO_SMALL);
 }
 
 static void
 ReportTooBigCharacter(JSContext* cx, uint32_t v)
 {
     char buffer[10];
     SprintfLiteral(buffer, "0x%x", v + 0x10000);
-    JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
-                                      JSMSG_UTF8_CHAR_TOO_LARGE, buffer);
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_UTF8_CHAR_TOO_LARGE, buffer);
 }
 
 enum InflateUTF8Action {
     CountAndReportInvalids,
     CountAndIgnoreInvalids,
     AssertNoInvalids,
     Copy,
     FindEncoding
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -269,19 +269,18 @@ GetOrCreateFunctionScript(JSContext* cx,
 
 static bool
 ValueToIdentifier(JSContext* cx, HandleValue v, MutableHandleId id)
 {
     if (!ValueToId<CanGC>(cx, v, id))
         return false;
     if (!JSID_IS_ATOM(id) || !IsIdentifier(JSID_TO_ATOM(id))) {
         RootedValue val(cx, v);
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                              JSDVG_SEARCH_STACK, val, nullptr, "not an identifier",
-                              nullptr);
+        ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, val, nullptr,
+                         "not an identifier");
         return false;
     }
     return true;
 }
 
 class js::AutoRestoreRealmDebugMode
 {
     Realm* realm_;
@@ -517,23 +516,21 @@ RequireGlobalObject(JSContext* cx, Handl
 
         /* ... and WindowProxies around Windows. */
         if (IsWindowProxy(obj)) {
             obj = ToWindowIfWindowProxy(obj);
             isWindowProxy = "a WindowProxy referring to ";
         }
 
         if (obj->is<GlobalObject>()) {
-            ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_DEBUG_WRAPPER_IN_WAY,
-                                  JSDVG_SEARCH_STACK, dbgobj, nullptr,
-                                  isWrapper, isWindowProxy);
+            ReportValueError(cx, JSMSG_DEBUG_WRAPPER_IN_WAY, JSDVG_SEARCH_STACK, dbgobj, nullptr,
+                             isWrapper, isWindowProxy);
         } else {
-            ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_DEBUG_BAD_REFERENT,
-                                  JSDVG_SEARCH_STACK, dbgobj, nullptr,
-                                  "a global object", nullptr);
+            ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK, dbgobj, nullptr,
+                             "a global object");
         }
         return false;
     }
 
     return true;
 }
 
 
@@ -5356,19 +5353,18 @@ static JSObject*
 DebuggerScript_checkThis(JSContext* cx, const CallArgs& args, const char* fnname,
                          const char* refname)
 {
     JSObject* thisobj = DebuggerScript_check(cx, args.thisv(), fnname);
     if (!thisobj)
         return nullptr;
 
     if (!GetScriptReferent(thisobj).is<ReferentT>()) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_DEBUG_BAD_REFERENT,
-                              JSDVG_SEARCH_STACK, args.thisv(), nullptr,
-                              refname, nullptr);
+        ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK, args.thisv(), nullptr,
+                         refname);
         return nullptr;
     }
 
     return thisobj;
 }
 
 #define THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, fnname, args, obj, referent)        \
     CallArgs args = CallArgsFromVp(argc, vp);                                       \
@@ -7002,19 +6998,18 @@ static NativeObject*
 DebuggerSource_checkThis(JSContext* cx, const CallArgs& args, const char* fnname,
                          const char* refname)
 {
     NativeObject* thisobj = DebuggerSource_check(cx, args.thisv(), fnname);
     if (!thisobj)
         return nullptr;
 
     if (!GetSourceReferent(thisobj).is<ReferentT>()) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_DEBUG_BAD_REFERENT,
-                              JSDVG_SEARCH_STACK, args.thisv(), nullptr,
-                              refname, nullptr);
+        ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK, args.thisv(), nullptr,
+                         refname);
         return nullptr;
     }
 
     return thisobj;
 }
 
 #define THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, fnname, args, obj, referent)        \
     CallArgs args = CallArgsFromVp(argc, vp);                                       \
@@ -7087,19 +7082,18 @@ DebuggerSource_getText(JSContext* cx, un
 }
 
 static bool
 DebuggerSource_getBinary(JSContext* cx, unsigned argc, Value* vp)
 {
     THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "(get binary)", args, obj, referent);
 
     if (!referent.is<WasmInstanceObject*>()) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_DEBUG_BAD_REFERENT,
-                              JSDVG_SEARCH_STACK, args.thisv(), nullptr,
-                              "a wasm source", nullptr);
+        ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK, args.thisv(), nullptr,
+                         "a wasm source");
         return false;
     }
 
     RootedWasmInstanceObject wasmInstance(cx, referent.as<WasmInstanceObject*>());
     if (!wasmInstance->instance().debug().binarySource()) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                                   JSMSG_DEBUG_NO_BINARY_SOURCE);
         return false;
@@ -8092,19 +8086,18 @@ DebuggerFrame::getFrameIter(JSContext* c
 }
 
 /* static */ bool
 DebuggerFrame::requireScriptReferent(JSContext* cx, HandleDebuggerFrame frame)
 {
     AbstractFramePtr referent = DebuggerFrame::getReferent(frame);
     if (!referent.hasScript()) {
         RootedValue frameobj(cx, ObjectValue(*frame));
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_DEBUG_BAD_REFERENT,
-                              JSDVG_SEARCH_STACK, frameobj, nullptr,
-                              "a script frame", nullptr);
+        ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK, frameobj, nullptr,
+                         "a script frame");
         return false;
     }
     return true;
 }
 
 void
 DebuggerFrame::freeFrameIterData(FreeOp* fop)
 {
@@ -10702,23 +10695,21 @@ DebuggerObject::requireGlobal(JSContext*
         /* ... and WindowProxies around Windows. */
         if (IsWindowProxy(referent)) {
             referent = ToWindowIfWindowProxy(referent);
             isWindowProxy = "a WindowProxy referring to ";
         }
 
         RootedValue dbgobj(cx, ObjectValue(*object));
         if (referent->is<GlobalObject>()) {
-            ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_DEBUG_WRAPPER_IN_WAY,
-                                  JSDVG_SEARCH_STACK, dbgobj, nullptr,
-                                  isWrapper, isWindowProxy);
+            ReportValueError(cx, JSMSG_DEBUG_WRAPPER_IN_WAY, JSDVG_SEARCH_STACK, dbgobj, nullptr,
+                             isWrapper, isWindowProxy);
         } else {
-            ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_DEBUG_BAD_REFERENT,
-                                  JSDVG_SEARCH_STACK, dbgobj, nullptr,
-                                  "a global object", nullptr);
+            ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK, dbgobj, nullptr,
+                             "a global object");
         }
         return false;
     }
 
     return true;
 }
 
 /* static */ bool
--- a/js/src/vm/ErrorObject.cpp
+++ b/js/src/vm/ErrorObject.cpp
@@ -4,16 +4,18 @@
  * 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/. */
 
 #include "vm/ErrorObject-inl.h"
 
 #include "mozilla/Range.h"
 
+#include <utility>
+
 #include "jsexn.h"
 
 #include "js/CallArgs.h"
 #include "js/CharacterEncoding.h"
 #include "vm/GlobalObject.h"
 #include "vm/SelfHosting.h"
 #include "vm/StringType.h"
 
@@ -33,17 +35,17 @@ js::ErrorObject::assignInitialShape(JSCo
         return nullptr;
     if (!NativeObject::addDataProperty(cx, obj, cx->names().lineNumber, LINENUMBER_SLOT, 0))
         return nullptr;
     return NativeObject::addDataProperty(cx, obj, cx->names().columnNumber, COLUMNNUMBER_SLOT, 0);
 }
 
 /* static */ bool
 js::ErrorObject::init(JSContext* cx, Handle<ErrorObject*> obj, JSExnType type,
-                      ScopedJSFreePtr<JSErrorReport>* errorReport, HandleString fileName,
+                      UniquePtr<JSErrorReport> errorReport, HandleString fileName,
                       HandleObject stack, uint32_t lineNumber, uint32_t columnNumber,
                       HandleString message)
 {
     AssertObjectIsSavedFrameOrWrapper(cx, stack);
     assertSameCompartment(cx, obj, stack);
 
     // Null out early in case of error, for exn_finalize's sake.
     obj->initReservedSlot(ERROR_REPORT_SLOT, PrivateValue(nullptr));
@@ -67,33 +69,33 @@ js::ErrorObject::init(JSContext* cx, Han
     MOZ_ASSERT(obj->lookupPure(NameToId(cx->names().lineNumber))->slot() == LINENUMBER_SLOT);
     MOZ_ASSERT(obj->lookupPure(NameToId(cx->names().columnNumber))->slot() ==
                COLUMNNUMBER_SLOT);
     MOZ_ASSERT_IF(message,
                   obj->lookupPure(NameToId(cx->names().message))->slot() == MESSAGE_SLOT);
 
     MOZ_ASSERT(JSEXN_ERR <= type && type < JSEXN_LIMIT);
 
-    JSErrorReport* report = errorReport ? errorReport->forget() : nullptr;
+    JSErrorReport* report = errorReport.release();
     obj->initReservedSlot(EXNTYPE_SLOT, Int32Value(type));
     obj->initReservedSlot(STACK_SLOT, ObjectOrNullValue(stack));
     obj->setReservedSlot(ERROR_REPORT_SLOT, PrivateValue(report));
     obj->initReservedSlot(FILENAME_SLOT, StringValue(fileName));
     obj->initReservedSlot(LINENUMBER_SLOT, Int32Value(lineNumber));
     obj->initReservedSlot(COLUMNNUMBER_SLOT, Int32Value(columnNumber));
     if (message)
         obj->setSlotWithType(cx, messageShape, StringValue(message));
 
     return true;
 }
 
 /* static */ ErrorObject*
 js::ErrorObject::create(JSContext* cx, JSExnType errorType, HandleObject stack,
                         HandleString fileName, uint32_t lineNumber, uint32_t columnNumber,
-                        ScopedJSFreePtr<JSErrorReport>* report, HandleString message,
+                        UniquePtr<JSErrorReport> report, HandleString message,
                         HandleObject protoArg /* = nullptr */)
 {
     AssertObjectIsSavedFrameOrWrapper(cx, stack);
 
     RootedObject proto(cx, protoArg);
     if (!proto) {
         proto = GlobalObject::getOrCreateCustomErrorPrototype(cx, cx->global(), errorType);
         if (!proto)
@@ -104,17 +106,17 @@ js::ErrorObject::create(JSContext* cx, J
     {
         const Class* clasp = ErrorObject::classForType(errorType);
         JSObject* obj = NewObjectWithGivenProto(cx, clasp, proto);
         if (!obj)
             return nullptr;
         errObject = &obj->as<ErrorObject>();
     }
 
-    if (!ErrorObject::init(cx, errObject, errorType, report, fileName, stack,
+    if (!ErrorObject::init(cx, errObject, errorType, std::move(report), fileName, stack,
                            lineNumber, columnNumber, message))
     {
         return nullptr;
     }
 
     return errObject;
 }
 
@@ -151,21 +153,21 @@ js::ErrorObject::getOrCreateErrorReport(
         return nullptr;
 
     UniqueChars utf8 = StringToNewUTF8CharsZ(cx, *message);
     if (!utf8)
         return nullptr;
     report.initOwnedMessage(utf8.release());
 
     // Cache and return.
-    JSErrorReport* copy = CopyErrorReport(cx, &report);
+    UniquePtr<JSErrorReport> copy = CopyErrorReport(cx, &report);
     if (!copy)
         return nullptr;
-    setReservedSlot(ERROR_REPORT_SLOT, PrivateValue(copy));
-    return copy;
+    setReservedSlot(ERROR_REPORT_SLOT, PrivateValue(copy.get()));
+    return copy.release();
 }
 
 static bool
 FindErrorInstanceOrPrototype(JSContext* cx, HandleObject obj, MutableHandleObject result)
 {
     // Walk up the prototype chain until we find an error object instance or
     // prototype object. This allows code like:
     //  Object.create(Error.prototype).stack
--- a/js/src/vm/ErrorObject.h
+++ b/js/src/vm/ErrorObject.h
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef vm_ErrorObject_h_
 #define vm_ErrorObject_h_
 
 #include "mozilla/ArrayUtils.h"
 
+#include "js/UniquePtr.h"
 #include "vm/NativeObject.h"
 #include "vm/SavedStacks.h"
 #include "vm/Shape.h"
 
 namespace js {
 
 /*
  * Initialize the exception constructor/prototype hierarchy.
@@ -30,17 +31,17 @@ class ErrorObject : public NativeObject
     createConstructor(JSContext* cx, JSProtoKey key);
 
     /* For access to createProto. */
     friend JSObject*
     js::InitExceptionClasses(JSContext* cx, HandleObject global);
 
     static bool
     init(JSContext* cx, Handle<ErrorObject*> obj, JSExnType type,
-         ScopedJSFreePtr<JSErrorReport>* errorReport, HandleString fileName, HandleObject stack,
+         UniquePtr<JSErrorReport> errorReport, HandleString fileName, HandleObject stack,
          uint32_t lineNumber, uint32_t columnNumber, HandleString message);
 
     static const ClassSpec classSpecs[JSEXN_ERROR_LIMIT];
     static const Class protoClasses[JSEXN_ERROR_LIMIT];
 
   protected:
     static const uint32_t EXNTYPE_SLOT          = 0;
     static const uint32_t STACK_SLOT            = EXNTYPE_SLOT + 1;
@@ -65,17 +66,17 @@ class ErrorObject : public NativeObject
     }
 
     // Create an error of the given type corresponding to the provided location
     // info.  If |message| is non-null, then the error will have a .message
     // property with that value; otherwise the error will have no .message
     // property.
     static ErrorObject*
     create(JSContext* cx, JSExnType type, HandleObject stack, HandleString fileName,
-           uint32_t lineNumber, uint32_t columnNumber, ScopedJSFreePtr<JSErrorReport>* report,
+           uint32_t lineNumber, uint32_t columnNumber, UniquePtr<JSErrorReport> report,
            HandleString message, HandleObject proto = nullptr);
 
     /*
      * Assign the initial error shape to the empty object.  (This shape does
      * *not* include .message, which must be added separately if needed; see
      * ErrorObject::init.)
      */
     static Shape*
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -989,17 +989,17 @@ js::CheckClassHeritageOperation(JSContex
     if (heritage.isNull())
         return true;
 
     if (heritage.isObject()) {
         ReportIsNotFunction(cx, heritage, 0, CONSTRUCT);
         return false;
     }
 
-    ReportValueError2(cx, JSMSG_BAD_HERITAGE, -1, heritage, nullptr, "not an object or null");
+    ReportValueError(cx, JSMSG_BAD_HERITAGE, -1, heritage, nullptr, "not an object or null");
     return false;
 }
 
 JSObject*
 js::ObjectWithProtoOperation(JSContext* cx, HandleValue val)
 {
     if (!val.isObjectOrNull()) {
         ReportValueError(cx, JSMSG_NOT_OBJORNULL, -1, val, nullptr);
--- a/js/src/vm/JSContext.cpp
+++ b/js/src/vm/JSContext.cpp
@@ -890,46 +890,36 @@ js::ReportIsNotDefined(JSContext* cx, Ha
 
 void
 js::ReportIsNotDefined(JSContext* cx, HandlePropertyName name)
 {
     RootedId id(cx, NameToId(name));
     ReportIsNotDefined(cx, id);
 }
 
-bool
-js::ReportIsNullOrUndefined(JSContext* cx, int spindex, HandleValue v,
-                            HandleString fallback)
+void
+js::ReportIsNullOrUndefined(JSContext* cx, int spindex, HandleValue v)
 {
-    bool ok;
-
-    UniqueChars bytes = DecompileValueGenerator(cx, spindex, v, fallback);
-    if (!bytes)
-        return false;
+    MOZ_ASSERT(v.isNullOrUndefined());
 
-    if (strcmp(bytes.get(), js_undefined_str) == 0 ||
-        strcmp(bytes.get(), js_null_str) == 0) {
-        ok = JS_ReportErrorFlagsAndNumberLatin1(cx, JSREPORT_ERROR,
-                                                GetErrorMessage, nullptr,
-                                                JSMSG_NO_PROPERTIES,
-                                                bytes.get());
+    UniqueChars bytes = DecompileValueGenerator(cx, spindex, v, nullptr);
+    if (!bytes)
+        return;
+
+    if (strcmp(bytes.get(), js_undefined_str) == 0 || strcmp(bytes.get(), js_null_str) == 0) {
+        JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NO_PROPERTIES,
+                                   bytes.get());
     } else if (v.isUndefined()) {
-        ok = JS_ReportErrorFlagsAndNumberLatin1(cx, JSREPORT_ERROR,
-                                                GetErrorMessage, nullptr,
-                                                JSMSG_UNEXPECTED_TYPE,
-                                                bytes.get(), js_undefined_str);
+        JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE,
+                                   bytes.get(), js_undefined_str);
     } else {
         MOZ_ASSERT(v.isNull());
-        ok = JS_ReportErrorFlagsAndNumberLatin1(cx, JSREPORT_ERROR,
-                                                GetErrorMessage, nullptr,
-                                                JSMSG_UNEXPECTED_TYPE,
-                                                bytes.get(), js_null_str);
+        JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE,
+                                   bytes.get(), js_null_str);
     }
-
-    return ok;
 }
 
 void
 js::ReportMissingArg(JSContext* cx, HandleValue v, unsigned arg)
 {
     char argbuf[11];
     UniqueChars bytes;
 
@@ -945,28 +935,24 @@ js::ReportMissingArg(JSContext* cx, Hand
                                argbuf, bytes ? bytes.get() : "");
 }
 
 bool
 js::ReportValueErrorFlags(JSContext* cx, unsigned flags, const unsigned errorNumber,
                           int spindex, HandleValue v, HandleString fallback,
                           const char* arg1, const char* arg2)
 {
-    UniqueChars bytes;
-    bool ok;
-
     MOZ_ASSERT(js_ErrorFormatString[errorNumber].argCount >= 1);
     MOZ_ASSERT(js_ErrorFormatString[errorNumber].argCount <= 3);
-    bytes = DecompileValueGenerator(cx, spindex, v, fallback);
+    UniqueChars bytes = DecompileValueGenerator(cx, spindex, v, fallback);
     if (!bytes)
         return false;
 
-    ok = JS_ReportErrorFlagsAndNumberLatin1(cx, flags, GetErrorMessage, nullptr, errorNumber,
-                                            bytes.get(), arg1, arg2);
-    return ok;
+    return JS_ReportErrorFlagsAndNumberLatin1(cx, flags, GetErrorMessage, nullptr, errorNumber,
+                                              bytes.get(), arg1, arg2);
 }
 
 JSObject*
 js::CreateErrorNotesArray(JSContext* cx, JSErrorReport* report)
 {
     RootedArrayObject notesArray(cx, NewDenseEmptyArray(cx));
     if (!notesArray)
         return nullptr;
--- a/js/src/vm/JSContext.h
+++ b/js/src/vm/JSContext.h
@@ -1010,43 +1010,38 @@ extern void
 ReportIsNotDefined(JSContext* cx, HandlePropertyName name);
 
 extern void
 ReportIsNotDefined(JSContext* cx, HandleId id);
 
 /*
  * Report an attempt to access the property of a null or undefined value (v).
  */
-extern bool
-ReportIsNullOrUndefined(JSContext* cx, int spindex, HandleValue v, HandleString fallback);
+extern void
+ReportIsNullOrUndefined(JSContext* cx, int spindex, HandleValue v);
 
 extern void
 ReportMissingArg(JSContext* cx, js::HandleValue v, unsigned arg);
 
 /*
  * Report error using js_DecompileValueGenerator(cx, spindex, v, fallback) as
  * the first argument for the error message. If the error message has less
  * then 3 arguments, use null for arg1 or arg2.
  */
 extern bool
 ReportValueErrorFlags(JSContext* cx, unsigned flags, const unsigned errorNumber,
                       int spindex, HandleValue v, HandleString fallback,
                       const char* arg1, const char* arg2);
 
-#define ReportValueError(cx,errorNumber,spindex,v,fallback)                   \
-    ((void)ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber,             \
-                                    spindex, v, fallback, nullptr, nullptr))
-
-#define ReportValueError2(cx,errorNumber,spindex,v,fallback,arg1)             \
-    ((void)ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber,             \
-                                    spindex, v, fallback, arg1, nullptr))
-
-#define ReportValueError3(cx,errorNumber,spindex,v,fallback,arg1,arg2)        \
-    ((void)ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber,             \
-                                    spindex, v, fallback, arg1, arg2))
+inline void
+ReportValueError(JSContext* cx, const unsigned errorNumber, int spindex, HandleValue v,
+                 HandleString fallback, const char* arg1 = nullptr, const char* arg2 = nullptr)
+{
+    ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber, spindex, v, fallback, arg1, arg2);
+}
 
 JSObject*
 CreateErrorNotesArray(JSContext* cx, JSErrorReport* report);
 
 } /* namespace js */
 
 extern const JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
 
--- a/js/src/vm/JSFunction.cpp
+++ b/js/src/vm/JSFunction.cpp
@@ -111,18 +111,17 @@ AdvanceToActiveCallLinear(JSContext* cx,
             return true;
     }
     return false;
 }
 
 void
 js::ThrowTypeErrorBehavior(JSContext* cx)
 {
-    JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
-                                     JSMSG_THROW_TYPE_ERROR);
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_THROW_TYPE_ERROR);
 }
 
 static bool
 IsSloppyNormalFunction(JSFunction* fun)
 {
     // FunctionDeclaration or FunctionExpression in sloppy mode.
     if (fun->kind() == JSFunction::NormalFunction) {
         if (fun->isBuiltin() || fun->isBoundFunction())
@@ -306,18 +305,17 @@ CallerGetterImpl(JSContext* cx, const Ca
         JSFunction* callerFun = &callerObj->as<JSFunction>();
         if (IsWrappedAsyncFunction(callerFun))
             callerFun = GetUnwrappedAsyncFunction(callerFun);
         else if (IsWrappedAsyncGenerator(callerFun))
             callerFun = GetUnwrappedAsyncGenerator(callerFun);
         MOZ_ASSERT(!callerFun->isBuiltin(), "non-builtin iterator returned a builtin?");
 
         if (callerFun->strict()) {
-            JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
-                                              JSMSG_CALLER_IS_STRICT);
+            JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CALLER_IS_STRICT);
             return false;
         }
     }
 
     args.rval().setObject(*caller);
     return true;
 }
 
@@ -375,18 +373,17 @@ CallerSetterImpl(JSContext* cx, const Ca
     JSObject* callerObj = CheckedUnwrap(caller);
     if (!callerObj)
         return true;
 
     JSFunction* callerFun = &callerObj->as<JSFunction>();
     MOZ_ASSERT(!callerFun->isBuiltin(), "non-builtin iterator returned a builtin?");
 
     if (callerFun->strict()) {
-        JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
-                                          JSMSG_CALLER_IS_STRICT);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CALLER_IS_STRICT);
         return false;
     }
 
     return true;
 }
 
 static bool
 CallerSetter(JSContext* cx, unsigned argc, Value* vp)
--- a/js/src/vm/JSObject.cpp
+++ b/js/src/vm/JSObject.cpp
@@ -2619,43 +2619,16 @@ js::HasOwnDataPropertyPure(JSContext* cx
     if (!LookupOwnPropertyPure(cx, obj, id, &prop))
         return false;
 
     *result = prop && !prop.isDenseOrTypedArrayElement() &&
               prop.shape()->isDataProperty();
     return true;
 }
 
-/* static */ bool
-JSObject::reportReadOnly(JSContext* cx, jsid id, unsigned report)
-{
-    RootedValue val(cx, IdToValue(id));
-    return ReportValueErrorFlags(cx, report, JSMSG_READ_ONLY,
-                                 JSDVG_IGNORE_STACK, val, nullptr,
-                                 nullptr, nullptr);
-}
-
-/* static */ bool
-JSObject::reportNotConfigurable(JSContext* cx, jsid id, unsigned report)
-{
-    RootedValue val(cx, IdToValue(id));
-    return ReportValueErrorFlags(cx, report, JSMSG_CANT_DELETE,
-                                 JSDVG_IGNORE_STACK, val, nullptr,
-                                 nullptr, nullptr);
-}
-
-/* static */ bool
-JSObject::reportNotExtensible(JSContext* cx, HandleObject obj, unsigned report)
-{
-    RootedValue val(cx, ObjectValue(*obj));
-    return ReportValueErrorFlags(cx, report, JSMSG_OBJECT_NOT_EXTENSIBLE,
-                                 JSDVG_IGNORE_STACK, val, nullptr,
-                                 nullptr, nullptr);
-}
-
 bool
 js::GetPrototypeIfOrdinary(JSContext* cx, HandleObject obj, bool* isOrdinary,
                            MutableHandleObject protop)
 {
     if (obj->is<js::ProxyObject>())
         return js::Proxy::getPrototypeIfOrdinary(cx, obj, isOrdinary, protop);
 
     *isOrdinary = true;
@@ -3081,20 +3054,20 @@ ReportCantConvert(JSContext* cx, unsigne
         str = JS_AtomizeAndPinString(cx, clasp->name);
         if (!str)
             return false;
     } else {
         str = nullptr;
     }
 
     RootedValue val(cx, ObjectValue(*obj));
-    ReportValueError2(cx, errorNumber, JSDVG_SEARCH_STACK, val, str,
-                      hint == JSTYPE_UNDEFINED
-                      ? "primitive type"
-                      : hint == JSTYPE_STRING ? "string" : "number");
+    ReportValueError(cx, errorNumber, JSDVG_SEARCH_STACK, val, str,
+                     hint == JSTYPE_UNDEFINED
+                     ? "primitive type"
+                     : hint == JSTYPE_STRING ? "string" : "number");
     return false;
 }
 
 bool
 JS::OrdinaryToPrimitive(JSContext* cx, HandleObject obj, JSType hint, MutableHandleValue vp)
 {
     MOZ_ASSERT(hint == JSTYPE_NUMBER || hint == JSTYPE_STRING || hint == JSTYPE_UNDEFINED);
 
@@ -3268,30 +3241,30 @@ js::PrimitiveToObject(JSContext* cx, con
     MOZ_ASSERT(v.isSymbol());
     RootedSymbol symbol(cx, v.toSymbol());
     return SymbolObject::create(cx, symbol);
 #endif
 }
 
 /*
  * Invokes the ES5 ToObject algorithm on vp, returning the result. If vp might
- * already be an object, use ToObject. reportCantConvert controls how null and
+ * already be an object, use ToObject. reportScanStack controls how null and
  * undefined errors are reported.
  *
  * Callers must handle the already-object case.
  */
 JSObject*
 js::ToObjectSlow(JSContext* cx, JS::HandleValue val, bool reportScanStack)
 {
     MOZ_ASSERT(!val.isMagic());
     MOZ_ASSERT(!val.isObject());
 
     if (val.isNullOrUndefined()) {
         if (reportScanStack) {
-            ReportIsNullOrUndefined(cx, JSDVG_SEARCH_STACK, val, nullptr);
+            ReportIsNullOrUndefined(cx, JSDVG_SEARCH_STACK, val);
         } else {
             JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CANT_CONVERT_TO,
                                       val.isNull() ? "null" : "undefined", "object");
         }
         return nullptr;
     }
 
     return PrimitiveToObject(cx, val);
--- a/js/src/vm/JSObject.h
+++ b/js/src/vm/JSObject.h
@@ -475,21 +475,16 @@ class JSObject : public js::gc::Cell
     MOZ_ALWAYS_INLINE bool isCallable() const;
     MOZ_ALWAYS_INLINE bool isConstructor() const;
     MOZ_ALWAYS_INLINE JSNative callHook() const;
     MOZ_ALWAYS_INLINE JSNative constructHook() const;
 
     MOZ_ALWAYS_INLINE void finalize(js::FreeOp* fop);
 
   public:
-    static bool reportReadOnly(JSContext* cx, jsid id, unsigned report = JSREPORT_ERROR);
-    static bool reportNotConfigurable(JSContext* cx, jsid id, unsigned report = JSREPORT_ERROR);
-    static bool reportNotExtensible(JSContext* cx, js::HandleObject obj,
-                                    unsigned report = JSREPORT_ERROR);
-
     static bool nonNativeSetProperty(JSContext* cx, js::HandleObject obj, js::HandleId id,
                                      js::HandleValue v, js::HandleValue receiver,
                                      JS::ObjectOpResult& result);
     static bool nonNativeSetElement(JSContext* cx, js::HandleObject obj, uint32_t index,
                                     js::HandleValue v, js::HandleValue receiver,
                                     JS::ObjectOpResult& result);
 
     static bool swap(JSContext* cx, JS::HandleObject a, JS::HandleObject b);
--- a/js/src/vm/NativeObject-inl.h
+++ b/js/src/vm/NativeObject-inl.h
@@ -962,18 +962,19 @@ LookupPropertyInline(JSContext* cx,
     return true;
 }
 
 inline bool
 ThrowIfNotConstructing(JSContext *cx, const CallArgs &args, const char *builtinName)
 {
     if (args.isConstructing())
         return true;
-    return JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
-                                             JSMSG_BUILTIN_CTOR_NO_NEW, builtinName);
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BUILTIN_CTOR_NO_NEW,
+                              builtinName);
+    return false;
 }
 
 inline bool
 IsPackedArray(JSObject* obj)
 {
     if (!obj->is<ArrayObject>() || obj->hasLazyGroup())
         return false;
     AutoSweepObjectGroup sweep(obj->group());
--- a/js/src/vm/NativeObject.cpp
+++ b/js/src/vm/NativeObject.cpp
@@ -1702,28 +1702,18 @@ js::NativeDefineProperty(JSContext* cx, 
         // type for this property that doesn't match the value in the slot.
         // Update the type here, even though this DefineProperty call is
         // otherwise a no-op. (See bug 1125624 comment 13.)
         if (!prop.isDenseOrTypedArrayElement() && desc.hasValue())
             UpdateShapeTypeAndValue(cx, obj, prop.shape(), id, desc.value());
         return result.succeed();
     }
 
-    // Non-standard hack: Allow redefining non-configurable properties if
-    // JSPROP_REDEFINE_NONCONFIGURABLE is set _and_ the object is a non-DOM
-    // global. The idea is that a DOM object can never have such a thing on
-    // its proto chain directly on the web, so we should be OK optimizing
-    // access to accessors found on such an object. Bug 1105518 contemplates
-    // removing this hack.
-    bool skipRedefineChecks = (desc.attributes() & JSPROP_REDEFINE_NONCONFIGURABLE) &&
-                              obj->is<GlobalObject>() &&
-                              !obj->getClass()->isDOMClass();
-
     // Step 4.
-    if (!IsConfigurable(shapeAttrs) && !skipRedefineChecks) {
+    if (!IsConfigurable(shapeAttrs)) {
         if (desc.hasConfigurable() && desc.configurable())
             return result.fail(JSMSG_CANT_REDEFINE_PROP);
         if (desc.hasEnumerable() && desc.enumerable() != IsEnumerable(shapeAttrs))
             return result.fail(JSMSG_CANT_REDEFINE_PROP);
     }
 
     // Fill in desc.[[Configurable]] and desc.[[Enumerable]] if missing.
     if (!desc.hasConfigurable())
@@ -1748,79 +1738,77 @@ js::NativeDefineProperty(JSContext* cx, 
             desc.setValue(currentValue);
             desc.setWritable(IsWritable(shapeAttrs));
         } else {
             desc.setGetterObject(prop.shape()->getterObject());
             desc.setSetterObject(prop.shape()->setterObject());
         }
     } else if (desc.isDataDescriptor() != IsDataDescriptor(shapeAttrs)) {
         // Step 6.
-        if (!IsConfigurable(shapeAttrs) && !skipRedefineChecks)
+        if (!IsConfigurable(shapeAttrs))
             return result.fail(JSMSG_CANT_REDEFINE_PROP);
 
         // Fill in desc fields with default values (steps 6.b.i and 6.c.i).
         CompletePropertyDescriptor(&desc);
     } else if (desc.isDataDescriptor()) {
         // Step 7.
         bool frozen = !IsConfigurable(shapeAttrs) && !IsWritable(shapeAttrs);
 
         // Step 7.a.i.1.
-        if (frozen && desc.hasWritable() && desc.writable() && !skipRedefineChecks)
+        if (frozen && desc.hasWritable() && desc.writable())
             return result.fail(JSMSG_CANT_REDEFINE_PROP);
 
         if (frozen || !desc.hasValue()) {
             RootedValue currentValue(cx);
             if (!GetExistingPropertyValue(cx, obj, id, prop, &currentValue))
                 return false;
 
             if (!desc.hasValue()) {
                 // Fill in desc.[[Value]].
                 desc.setValue(currentValue);
             } else {
                 // Step 7.a.i.2.
                 bool same;
                 MOZ_ASSERT(!cx->helperThread());
                 if (!SameValue(cx, desc.value(), currentValue, &same))
                     return false;
-                if (!same && !skipRedefineChecks)
+                if (!same)
                     return result.fail(JSMSG_CANT_REDEFINE_PROP);
             }
         }
 
         // Step 7.a.i.3.
-        if (frozen && !skipRedefineChecks)
+        if (frozen)
             return result.succeed();
 
         // Fill in desc.[[Writable]].
         if (!desc.hasWritable())
             desc.setWritable(IsWritable(shapeAttrs));
     } else {
         // Step 8.
         MOZ_ASSERT(prop.shape()->isAccessorDescriptor());
         MOZ_ASSERT(desc.isAccessorDescriptor());
 
         // The spec says to use SameValue, but since the values in
         // question are objects, we can just compare pointers.
         if (desc.hasSetterObject()) {
             // Step 8.a.i.
             if (!IsConfigurable(shapeAttrs) &&
-                desc.setterObject() != prop.shape()->setterObject() &&
-                !skipRedefineChecks)
+                desc.setterObject() != prop.shape()->setterObject())
             {
                 return result.fail(JSMSG_CANT_REDEFINE_PROP);
             }
         } else {
             // Fill in desc.[[Set]] from shape.
             desc.setSetterObject(prop.shape()->setterObject());
         }
         if (desc.hasGetterObject()) {
             // Step 8.a.ii.
             if (!IsConfigurable(shapeAttrs) &&
-                desc.getterObject() != prop.shape()->getterObject() &&
-                !skipRedefineChecks)
+                desc.getterObject() != prop.shape()->getterObject())
             {
                 return result.fail(JSMSG_CANT_REDEFINE_PROP);
             }
         } else {
             // Fill in desc.[[Get]] from shape.
             desc.setGetterObject(prop.shape()->getterObject());
         }
 
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -1418,18 +1418,17 @@ js::ParseRegExpFlags(JSContext* cx, JSSt
         ok = ::ParseRegExpFlags(linear->twoByteChars(nogc), len, flagsOut, &invalidFlag);
     }
 
     if (!ok) {
         TwoByteChars range(&invalidFlag, 1);
         UniqueChars utf8(JS::CharsToNewUTF8CharsZ(nullptr, range).c_str());
         if (!utf8)
             return false;
-        JS_ReportErrorFlagsAndNumberUTF8(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
-                                         JSMSG_BAD_REGEXP_FLAG, utf8.get());
+        JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_BAD_REGEXP_FLAG, utf8.get());
         return false;
     }
 
     return true;
 }
 
 template<XDRMode mode>
 XDRResult
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -2901,18 +2901,18 @@ VerifyGlobalNames(JSContext* cx, Handle<
                     break;
                 }
             }
         }
     }
 
     if (nameMissing) {
         RootedValue value(cx, IdToValue(id));
-        return ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_NO_SUCH_SELF_HOSTED_PROP,
-                                     JSDVG_IGNORE_STACK, value, nullptr, nullptr, nullptr);
+        ReportValueError(cx, JSMSG_NO_SUCH_SELF_HOSTED_PROP, JSDVG_IGNORE_STACK, value, nullptr);
+        return false;
     }
 #endif // DEBUG
 
     return true;
 }
 
 bool
 JSRuntime::initSelfHosting(JSContext* cx)
--- a/layout/painting/DisplayItemClipChain.h
+++ b/layout/painting/DisplayItemClipChain.h
@@ -67,18 +67,19 @@ struct DisplayItemClipChain {
     , mASR(aASR)
     , mParent(aParent)
 #ifdef DEBUG
     , mOnStack(true)
 #endif
   {}
 
   DisplayItemClipChain()
+    : mASR(nullptr)
 #ifdef DEBUG
-    : mOnStack(true)
+    , mOnStack(true)
 #endif
   {}
 
   DisplayItemClip mClip;
   const ActiveScrolledRoot* mASR;
   RefPtr<const DisplayItemClipChain> mParent;
   uint32_t mRefCount = 0;
 #ifdef DEBUG
--- a/layout/painting/DottedCornerFinder.cpp
+++ b/layout/painting/DottedCornerFinder.cpp
@@ -52,17 +52,17 @@ DottedCornerFinder::DottedCornerFinder(c
                                        const Point& aCn, Float aRn,
                                        const Size& aCornerDim)
  : mOuterBezier(aOuterBezier),
    mInnerBezier(aInnerBezier),
    mCorner(aCorner),
    mNormalSign((aCorner == C_TL || aCorner == C_BR) ? -1.0f : 1.0f),
    mC0(aC0), mCn(aCn),
    mR0(aR0), mRn(aRn), mMaxR(std::max(aR0, aRn)),
-   mCenterCurveOrigin(mC0.x, mCn.y),
+   mCenterCurveOrigin(mC0.x, mCn.y), mCenterCurveR(0.0),
    mInnerCurveOrigin(mInnerBezier.mPoints[0].x, mInnerBezier.mPoints[3].y),
    mBestOverlap(0.0f),
    mHasZeroBorderWidth(false), mHasMore(true),
    mMaxCount(aCornerDim.width + aCornerDim.height),
    mType(OTHER),
    mI(0), mCount(0)
 {
   NS_ASSERTION(mR0 > 0.0f || mRn > 0.0f,
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -528,16 +528,17 @@ FrameLayerBuilder::DestroyDisplayItemDat
  * makes it more likely a display item will be rendered to an opaque
  * layer, giving us the best chance of getting subpixel AA.
  */
 class PaintedLayerData {
 public:
   PaintedLayerData() :
     mAnimatedGeometryRoot(nullptr),
     mASR(nullptr),
+    mClipChain(nullptr),
     mReferenceFrame(nullptr),
     mLayer(nullptr),
     mSolidColor(NS_RGBA(0, 0, 0, 0)),
     mIsSolidColorInVisibleRegion(false),
     mNeedComponentAlpha(false),
     mForceTransparentSurface(false),
     mHideAllLayersBelow(false),
     mOpaqueForAnimatedGeometryRootParent(false),
@@ -1632,17 +1633,18 @@ public:
   PaintedDisplayItemLayerUserData() :
     mForcedBackgroundColor(NS_RGBA(0,0,0,0)),
     mXScale(1.f), mYScale(1.f),
     mAppUnitsPerDevPixel(0),
     mTranslation(0, 0),
     mAnimatedGeometryRootPosition(0, 0),
     mLastItemCount(0),
     mContainerLayerFrame(nullptr),
-    mHasExplicitLastPaintOffset(false) {}
+    mHasExplicitLastPaintOffset(false),
+    mDisabledAlpha(false) {}
 
   NS_INLINE_DECL_REFCOUNTING(PaintedDisplayItemLayerUserData);
 
   /**
    * A color that should be painted over the bounds of the layer's visible
    * region before any other content is painted.
    */
   nscolor mForcedBackgroundColor;
@@ -1720,16 +1722,17 @@ public:
   bool mDisabledAlpha;
 
 protected:
   ~PaintedDisplayItemLayerUserData() = default;
 };
 
 FrameLayerBuilder::FrameLayerBuilder()
   : mRetainingManager(nullptr)
+  , mDisplayListBuilder(nullptr)
   , mContainingPaintedLayer(nullptr)
   , mInactiveLayerClip(nullptr)
   , mInvalidateAllLayers(false)
   , mInLayerTreeCompressionMode(false)
   , mIsInactiveLayerManager(false)
 {
   MOZ_COUNT_CTOR(FrameLayerBuilder);
 }
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -72,17 +72,20 @@ static int gFrameTreeLockCount = 0;
 
 // To avoid storing this data on nsInlineFrame (bloat) and to avoid
 // recalculating this for each frame in a continuation (perf), hold
 // a cache of various coordinate information that we need in order
 // to paint inline backgrounds.
 struct InlineBackgroundData
 {
   InlineBackgroundData()
-      : mFrame(nullptr), mLineContainer(nullptr)
+      : mFrame(nullptr), mLineContainer(nullptr),
+        mContinuationPoint(0), mUnbrokenMeasure(0), 
+        mLineContinuationPoint(0), mPIStartBorderData{},
+        mBidiEnabled(false), mVertical(false)
   {
   }
 
   ~InlineBackgroundData()
   {
   }
 
   void Reset()
--- a/layout/painting/nsCSSRenderingGradients.h
+++ b/layout/painting/nsCSSRenderingGradients.h
@@ -86,17 +86,22 @@ public:
                                   const nsRect& aDest,
                                   const nsRect& aFill,
                                   const nsSize& aRepeatSize,
                                   const mozilla::CSSIntRect& aSrc,
                                   bool aIsBackfaceVisible,
                                   float aOpacity = 1.0);
 
 private:
-  nsCSSGradientRenderer() {}
+  nsCSSGradientRenderer()
+    : mPresContext(nullptr)
+    , mGradient(nullptr)
+    , mRadiusX(0.0)
+    , mRadiusY(0.0)
+  {}
 
   /**
    * Attempts to paint the tiles for a gradient by painting it once to an
    * offscreen surface and then painting that offscreen surface with
    * ExtendMode::Repeat to cover all tiles.
    *
    * Returns false if the optimization wasn't able to be used, in which case
    * a fallback should be used.
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -318,16 +318,19 @@ struct ActiveScrolledRoot {
 
   RefPtr<const ActiveScrolledRoot> mParent;
   nsIScrollableFrame* mScrollableFrame;
 
   NS_INLINE_DECL_REFCOUNTING(ActiveScrolledRoot)
 
 private:
   ActiveScrolledRoot()
+    : mScrollableFrame(nullptr)
+    , mDepth(0)
+    , mRetained(false)
   {
   }
 
   ~ActiveScrolledRoot()
   {
     if (mScrollableFrame && mRetained) {
       nsIFrame* f = do_QueryFrame(mScrollableFrame);
       f->DeleteProperty(ActiveScrolledRootCache());
--- a/layout/painting/nsImageRenderer.h
+++ b/layout/painting/nsImageRenderer.h
@@ -28,18 +28,21 @@ class IpcResourceUpdateQueue;
 // A CSSSizeOrRatio represents a (possibly partially specified) size for use
 // in computing image sizes. Either or both of the width and height might be
 // given. A ratio of width to height may also be given. If we at least two
 // of these then we can compute a concrete size, that is a width and height.
 struct CSSSizeOrRatio
 {
   CSSSizeOrRatio()
     : mRatio(0, 0)
+    , mWidth(0)
+    , mHeight(0)
     , mHasWidth(false)
-    , mHasHeight(false) {}
+    , mHasHeight(false)
+  {}
 
   bool CanComputeConcreteSize() const
   {
     return mHasWidth + mHasHeight + HasRatio() >= 2;
   }
   bool IsConcrete() const { return mHasWidth && mHasHeight; }
   bool HasRatio() const { return mRatio.width > 0 && mRatio.height > 0; }
   bool IsEmpty() const
--- a/layout/svg/SVGContextPaint.h
+++ b/layout/svg/SVGContextPaint.h
@@ -185,17 +185,20 @@ public:
 
   void SetFillOpacity(float aOpacity) { mFillOpacity = aOpacity; }
   float GetFillOpacity() const override { return mFillOpacity; }
 
   void SetStrokeOpacity(float aOpacity) { mStrokeOpacity = aOpacity; }
   float GetStrokeOpacity() const override { return mStrokeOpacity; }
 
   struct Paint {
-    Paint() : mPaintType(eStyleSVGPaintType_None) {}
+    Paint()
+      : mPaintDefinition{}
+      , mPaintType(eStyleSVGPaintType_None)
+    {}
 
     void SetPaintServer(nsIFrame* aFrame,
                         const gfxMatrix& aContextMatrix,
                         nsSVGPaintServerFrame* aPaintServerFrame) {
       mPaintType = eStyleSVGPaintType_Server;
       mPaintDefinition.mPaintServerFrame = aPaintServerFrame;
       mFrame = aFrame;
       mContextMatrix = aContextMatrix;
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -2434,20 +2434,22 @@ CharIterator::CharIterator(SVGTextFrame*
                            CharIterator::CharacterFilter aFilter,
                            nsIContent* aSubtree,
                            bool aPostReflow)
   : mFilter(aFilter),
     mFrameIterator(aSVGTextFrame, aSubtree),
     mFrameForTrimCheck(nullptr),
     mTrimmedOffset(0),
     mTrimmedLength(0),
+    mTextRun(nullptr),
     mTextElementCharIndex(0),
     mGlyphStartTextElementCharIndex(0),
-    mLengthAdjustScaleFactor(aSVGTextFrame->mLengthAdjustScaleFactor)
-  , mPostReflow(aPostReflow)
+    mGlyphUndisplayedCharacters(0),
+    mLengthAdjustScaleFactor(aSVGTextFrame->mLengthAdjustScaleFactor),
+    mPostReflow(aPostReflow)
 {
   if (!AtEnd()) {
     mSkipCharsIterator = TextFrame()->EnsureTextRun(nsTextFrame::eInflated);
     mTextRun = TextFrame()->GetTextRun(nsTextFrame::eInflated);
     mTextElementCharIndex = mFrameIterator.UndisplayedCharacters();
     UpdateGlyphStartTextElementCharIndex();
     if (!MatchesFilter()) {
       Next();
@@ -2767,17 +2769,18 @@ public:
                            const gfxMatrix& aCanvasTM,
                            imgDrawingParams& aImgParams,
                            bool aShouldPaintSVGGlyphs)
     : DrawPathCallbacks(aShouldPaintSVGGlyphs),
       mSVGTextFrame(aSVGTextFrame),
       mContext(aContext),
       mFrame(aFrame),
       mCanvasTM(aCanvasTM),
-      mImgParams(aImgParams)
+      mImgParams(aImgParams),
+      mColor(0)
   {
   }
 
   void NotifySelectionBackgroundNeedsFill(const Rect& aBackgroundRect,
                                           nscolor aColor,
                                           DrawTarget& aDrawTarget) override;
   void PaintDecorationLine(Rect aPath, nscolor aColor) override;
   void PaintSelectionDecorationLine(Rect aPath, nscolor aColor) override;