Bug 1409227 (part 4) - Replace nsMemory::Clone(id, sizeof(nsID)) with nsID::Clone(id). r=mccr8.
authorNicholas Nethercote <nnethercote@mozilla.com>
Wed, 18 Oct 2017 10:39:20 +1100
changeset 386769 ec3abaf3421e48bc1bb8f7c720075d5fa486e7a6
parent 386768 48349c3ea33dab78bb7579a03ac5dd785c6fe46d
child 386770 0ac3f44070ff6419f04a494018bcc15781fcf4b6
push id96308
push usernnethercote@mozilla.com
push dateWed, 18 Oct 2017 02:24:02 +0000
treeherdermozilla-inbound@ec3abaf3421e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1409227
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1409227 (part 4) - Replace nsMemory::Clone(id, sizeof(nsID)) with nsID::Clone(id). r=mccr8. This change requires introducing nsID::Clone(). Because it's infallible, the patch also removes some redundant failure-handling code. (nsMemory::Clone() is also infallible, so this code was redundant even before this change.)
docshell/base/nsDocShell.cpp
docshell/shistory/nsSHEntry.cpp
dom/base/nsDOMClassInfo.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCRuntimeService.cpp
js/xpconnect/src/XPCWrappedJS.cpp
xpcom/base/nsIClassInfoImpl.h
xpcom/base/nsID.cpp
xpcom/base/nsID.h
xpcom/ds/nsSupportsPrimitives.cpp
xpcom/ds/nsVariant.cpp
xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
xpcom/reflect/xptinfo/xptiInterfaceInfo.cpp
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -4121,17 +4121,17 @@ nsDocShell::GetChildOffset(int32_t* aChi
 {
   *aChildOffset = mChildOffset;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetHistoryID(nsID** aID)
 {
-  *aID = static_cast<nsID*>(nsMemory::Clone(&mHistoryID, sizeof(nsID)));
+  *aID = mHistoryID.Clone();
   return NS_OK;
 }
 
 const nsID
 nsDocShell::HistoryID()
 {
   return mHistoryID;
 }
--- a/docshell/shistory/nsSHEntry.cpp
+++ b/docshell/shistory/nsSHEntry.cpp
@@ -954,17 +954,17 @@ nsSHEntry::HasDynamicallyAddedChild(bool
     }
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSHEntry::GetDocshellID(nsID** aID)
 {
-  *aID = static_cast<nsID*>(nsMemory::Clone(&mShared->mDocShellID, sizeof(nsID)));
+  *aID = mShared->mDocShellID.Clone();
   return NS_OK;
 }
 
 const nsID
 nsSHEntry::DocshellID()
 {
   return mShared->mDocShellID;
 }
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -539,30 +539,20 @@ nsDOMClassInfo::GetInterfaces(uint32_t *
 
   if (!count) {
     *aArray = nullptr;
 
     return NS_OK;
   }
 
   *aArray = static_cast<nsIID **>(moz_xmalloc(count * sizeof(nsIID *)));
-  NS_ENSURE_TRUE(*aArray, NS_ERROR_OUT_OF_MEMORY);
 
   uint32_t i;
   for (i = 0; i < count; i++) {
-    nsIID *iid = static_cast<nsIID *>(nsMemory::Clone(mData->mInterfaces[i],
-                                                         sizeof(nsIID)));
-
-    if (!iid) {
-      NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(i, *aArray);
-
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    *((*aArray) + i) = iid;
+    *((*aArray) + i) = mData->mInterfaces[i]->Clone();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMClassInfo::GetScriptableHelper(nsIXPCScriptable **_retval)
 {
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -118,43 +118,23 @@ private:
     virtual ~nsXPCComponents_Interfaces();
 
     nsCOMArray<nsIInterfaceInfo> mInterfaces;
 };
 
 NS_IMETHODIMP
 nsXPCComponents_Interfaces::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
 {
-    const uint32_t count = 2;
-    *aCount = count;
-    nsIID** array;
-    *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
-    if (!array)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    uint32_t index = 0;
-    nsIID* clone;
-#define PUSH_IID(id)                                                          \
-    clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
-                                                 sizeof(nsIID)));             \
-    if (!clone)                                                               \
-        goto oom;                                                             \
-    array[index++] = clone;
-
-    PUSH_IID(nsIXPCComponents_Interfaces)
-    PUSH_IID(nsIXPCScriptable)
-#undef PUSH_IID
-
+    *aCount = 2;
+    nsIID** array = static_cast<nsIID**>(moz_xmalloc(2 * sizeof(nsIID*)));
+    *aArray = array;
+
+    array[0] = NS_GET_IID(nsIXPCComponents_Interfaces).Clone();
+    array[1] = NS_GET_IID(nsIXPCScriptable).Clone();
     return NS_OK;
-oom:
-    while (index)
-        free(array[--index]);
-    free(array);
-    *aArray = nullptr;
-    return NS_ERROR_OUT_OF_MEMORY;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Interfaces::GetScriptableHelper(nsIXPCScriptable** retval)
 {
     *retval = nullptr;
     return NS_OK;
 }
@@ -342,43 +322,23 @@ private:
 
     nsCOMArray<nsIInterfaceInfo> mInterfaces;
 };
 
 /***************************************************************************/
 NS_IMETHODIMP
 nsXPCComponents_InterfacesByID::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
 {
-    const uint32_t count = 2;
-    *aCount = count;
-    nsIID** array;
-    *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
-    if (!array)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    uint32_t index = 0;
-    nsIID* clone;
-#define PUSH_IID(id)                                                          \
-    clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
-                                                 sizeof(nsIID)));             \
-    if (!clone)                                                               \
-        goto oom;                                                             \
-    array[index++] = clone;
-
-    PUSH_IID(nsIXPCComponents_InterfacesByID)
-    PUSH_IID(nsIXPCScriptable)
-#undef PUSH_IID
-
+    *aCount = 2;
+    nsIID** array = static_cast<nsIID**>(moz_xmalloc(2 * sizeof(nsIID*)));
+    *aArray = array;
+
+    array[0] = NS_GET_IID(nsIXPCComponents_InterfacesByID).Clone();
+    array[1] = NS_GET_IID(nsIXPCScriptable).Clone();
     return NS_OK;
-oom:
-    while (index)
-        free(array[--index]);
-    free(array);
-    *aArray = nullptr;
-    return NS_ERROR_OUT_OF_MEMORY;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_InterfacesByID::GetScriptableHelper(nsIXPCScriptable** retval)
 {
     *retval = nullptr;
     return NS_OK;
 }
@@ -568,43 +528,23 @@ public:
 private:
     virtual ~nsXPCComponents_Classes();
 };
 
 /***************************************************************************/
 NS_IMETHODIMP
 nsXPCComponents_Classes::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
 {
-    const uint32_t count = 2;
-    *aCount = count;
-    nsIID** array;
-    *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
-    if (!array)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    uint32_t index = 0;
-    nsIID* clone;
-#define PUSH_IID(id)                                                          \
-    clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
-                                                 sizeof(nsIID)));             \
-    if (!clone)                                                               \
-        goto oom;                                                             \
-    array[index++] = clone;
-
-    PUSH_IID(nsIXPCComponents_Classes)
-    PUSH_IID(nsIXPCScriptable)
-#undef PUSH_IID
-
+    *aCount = 2;
+    nsIID** array = static_cast<nsIID**>(moz_xmalloc(2 * sizeof(nsIID*)));
+    *aArray = array;
+
+    array[0] = NS_GET_IID(nsIXPCComponents_Classes).Clone();
+    array[1] = NS_GET_IID(nsIXPCScriptable).Clone();
     return NS_OK;
-oom:
-    while (index)
-        free(array[--index]);
-    free(array);
-    *aArray = nullptr;
-    return NS_ERROR_OUT_OF_MEMORY;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Classes::GetScriptableHelper(nsIXPCScriptable** retval)
 {
     *retval = nullptr;
     return NS_OK;
 }
@@ -782,43 +722,23 @@ public:
 private:
     virtual ~nsXPCComponents_ClassesByID();
 };
 
 /***************************************************************************/
 NS_IMETHODIMP
 nsXPCComponents_ClassesByID::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
 {
-    const uint32_t count = 2;
-    *aCount = count;
-    nsIID** array;
-    *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
-    if (!array)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    uint32_t index = 0;
-    nsIID* clone;
-#define PUSH_IID(id)                                                          \
-    clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
-                                                 sizeof(nsIID)));             \
-    if (!clone)                                                               \
-        goto oom;                                                             \
-    array[index++] = clone;
-
-    PUSH_IID(nsIXPCComponents_ClassesByID)
-    PUSH_IID(nsIXPCScriptable)
-#undef PUSH_IID
-
+    *aCount = 2;
+    nsIID** array = static_cast<nsIID**>(moz_xmalloc(2 * sizeof(nsIID*)));
+    *aArray = array;
+
+    array[0] = NS_GET_IID(nsIXPCComponents_ClassesByID).Clone();
+    array[1] = NS_GET_IID(nsIXPCScriptable).Clone();
     return NS_OK;
-oom:
-    while (index)
-        free(array[--index]);
-    free(array);
-    *aArray = nullptr;
-    return NS_ERROR_OUT_OF_MEMORY;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_ClassesByID::GetScriptableHelper(nsIXPCScriptable** retval)
 {
     *retval = nullptr;
     return NS_OK;
 }
@@ -1011,43 +931,23 @@ public:
 private:
     virtual ~nsXPCComponents_Results();
 };
 
 /***************************************************************************/
 NS_IMETHODIMP
 nsXPCComponents_Results::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
 {
-    const uint32_t count = 2;
-    *aCount = count;
-    nsIID** array;
-    *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
-    if (!array)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    uint32_t index = 0;
-    nsIID* clone;
-#define PUSH_IID(id)                                                          \
-    clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
-                                                 sizeof(nsIID)));             \
-    if (!clone)                                                               \
-        goto oom;                                                             \
-    array[index++] = clone;
-
-    PUSH_IID(nsIXPCComponents_Results)
-    PUSH_IID(nsIXPCScriptable)
-#undef PUSH_IID
-
+    *aCount = 2;
+    nsIID** array = static_cast<nsIID**>(moz_xmalloc(2 * sizeof(nsIID*)));
+    *aArray = array;
+
+    array[0] = NS_GET_IID(nsIXPCComponents_Results).Clone();
+    array[1] = NS_GET_IID(nsIXPCScriptable).Clone();
     return NS_OK;
-oom:
-    while (index)
-        free(array[--index]);
-    free(array);
-    *aArray = nullptr;
-    return NS_ERROR_OUT_OF_MEMORY;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Results::GetScriptableHelper(nsIXPCScriptable** retval)
 {
     *retval = nullptr;
     return NS_OK;
 }
@@ -1200,43 +1100,23 @@ private:
                                     JSContext* cx, HandleObject obj,
                                     const CallArgs& args, bool* _retval);
 };
 
 /***************************************************************************/
 NS_IMETHODIMP
 nsXPCComponents_ID::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
 {
-    const uint32_t count = 2;
-    *aCount = count;
-    nsIID** array;
-    *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
-    if (!array)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    uint32_t index = 0;
-    nsIID* clone;
-#define PUSH_IID(id)                                                          \
-    clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
-                                                 sizeof(nsIID)));             \
-    if (!clone)                                                               \
-        goto oom;                                                             \
-    array[index++] = clone;
-
-    PUSH_IID(nsIXPCComponents_ID)
-    PUSH_IID(nsIXPCScriptable)
-#undef PUSH_IID
-
+    *aCount = 2;
+    nsIID** array = static_cast<nsIID**>(moz_xmalloc(2 * sizeof(nsIID*)));
+    *aArray = array;
+
+    array[0] = NS_GET_IID(nsIXPCComponents_ID).Clone();
+    array[1] = NS_GET_IID(nsIXPCScriptable).Clone();
     return NS_OK;
-oom:
-    while (index)
-        free(array[--index]);
-    free(array);
-    *aArray = nullptr;
-    return NS_ERROR_OUT_OF_MEMORY;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_ID::GetScriptableHelper(nsIXPCScriptable** retval)
 {
     *retval = nullptr;
     return NS_OK;
 }
@@ -1396,43 +1276,23 @@ private:
                                     JSContext* cx, HandleObject obj,
                                     const CallArgs& args, bool* _retval);
 };
 
 /***************************************************************************/
 NS_IMETHODIMP
 nsXPCComponents_Exception::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
 {
-    const uint32_t count = 2;
-    *aCount = count;
-    nsIID** array;
-    *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
-    if (!array)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    uint32_t index = 0;
-    nsIID* clone;
-#define PUSH_IID(id)                                                          \
-    clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
-                                                 sizeof(nsIID)));             \
-    if (!clone)                                                               \
-        goto oom;                                                             \
-    array[index++] = clone;
-
-    PUSH_IID(nsIXPCComponents_Exception)
-    PUSH_IID(nsIXPCScriptable)
-#undef PUSH_IID
-
+    *aCount = 2;
+    nsIID** array = static_cast<nsIID**>(moz_xmalloc(2 * sizeof(nsIID*)));
+    *aArray = array;
+
+    array[0] = NS_GET_IID(nsIXPCComponents_Exception).Clone();
+    array[1] = NS_GET_IID(nsIXPCScriptable).Clone();
     return NS_OK;
-oom:
-    while (index)
-        free(array[--index]);
-    free(array);
-    *aArray = nullptr;
-    return NS_ERROR_OUT_OF_MEMORY;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Exception::GetScriptableHelper(nsIXPCScriptable** retval)
 {
     *retval = nullptr;
     return NS_OK;
 }
@@ -1759,43 +1619,23 @@ private:
     RefPtr<nsIJSIID> mInterfaceID;
     char*              mInitializer;
 };
 
 /***************************************************************************/
 NS_IMETHODIMP
 nsXPCConstructor::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
 {
-    const uint32_t count = 2;
-    *aCount = count;
-    nsIID** array;
-    *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
-    if (!array)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    uint32_t index = 0;
-    nsIID* clone;
-#define PUSH_IID(id)                                                          \
-    clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
-                                                 sizeof(nsIID)));             \
-    if (!clone)                                                               \
-        goto oom;                                                             \
-    array[index++] = clone;
-
-    PUSH_IID(nsIXPCConstructor)
-    PUSH_IID(nsIXPCScriptable)
-#undef PUSH_IID
-
+    *aCount = 2;
+    nsIID** array = static_cast<nsIID**>(moz_xmalloc(2 * sizeof(nsIID*)));
+    *aArray = array;
+
+    array[0] = NS_GET_IID(nsIXPCConstructor).Clone();
+    array[1] = NS_GET_IID(nsIXPCScriptable).Clone();
     return NS_OK;
-oom:
-    while (index)
-        free(array[--index]);
-    free(array);
-    *aArray = nullptr;
-    return NS_ERROR_OUT_OF_MEMORY;
 }
 
 NS_IMETHODIMP
 nsXPCConstructor::GetScriptableHelper(nsIXPCScriptable** retval)
 {
     *retval = nullptr;
     return NS_OK;
 }
@@ -1980,43 +1820,23 @@ private:
                                     JSContext* cx, HandleObject obj,
                                     const CallArgs& args, bool* _retval);
 };
 
 /***************************************************************************/
 NS_IMETHODIMP
 nsXPCComponents_Constructor::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
 {
-    const uint32_t count = 2;
-    *aCount = count;
-    nsIID** array;
-    *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
-    if (!array)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    uint32_t index = 0;
-    nsIID* clone;
-#define PUSH_IID(id)                                                          \
-    clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
-                                                 sizeof(nsIID)));             \
-    if (!clone)                                                               \
-        goto oom;                                                             \
-    array[index++] = clone;
-
-    PUSH_IID(nsIXPCComponents_Constructor)
-    PUSH_IID(nsIXPCScriptable)
-#undef PUSH_IID
-
+    *aCount = 2;
+    nsIID** array = static_cast<nsIID**>(moz_xmalloc(2 * sizeof(nsIID*)));
+    *aArray = array;
+
+    array[0] = NS_GET_IID(nsIXPCComponents_Constructor).Clone();
+    array[1] = NS_GET_IID(nsIXPCScriptable).Clone();
     return NS_OK;
-oom:
-    while (index)
-        free(array[--index]);
-    free(array);
-    *aArray = nullptr;
-    return NS_ERROR_OUT_OF_MEMORY;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Constructor::GetScriptableHelper(nsIXPCScriptable** retval)
 {
     *retval = nullptr;
     return NS_OK;
 }
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -476,21 +476,20 @@ XPCConvert::JSData2Native(void* d, Handl
         // There's no good reason to pass a null IID.
         if (s.isNullOrUndefined()) {
             if (pErr)
                 *pErr = NS_ERROR_XPC_BAD_CONVERT_JS;
             return false;
         }
 
         if (!s.isObject() ||
-            (!(pid = xpc_JSObjectToID(cx, &s.toObject()))) ||
-            (!(pid = (const nsID*) nsMemory::Clone(pid, sizeof(nsID))))) {
+            !(pid = xpc_JSObjectToID(cx, &s.toObject()))) {
             return false;
         }
-        *((const nsID**)d) = pid;
+        *((const nsID**)d) = pid->Clone();
         return true;
     }
 
     case nsXPTType::T_ASTRING:
     {
         if (s.isUndefined()) {
             (**((nsAString**)d)).SetIsVoid(true);
             return true;
--- a/js/xpconnect/src/XPCRuntimeService.cpp
+++ b/js/xpconnect/src/XPCRuntimeService.cpp
@@ -75,43 +75,23 @@ BackstagePass::Enumerate(nsIXPConnectWra
     *_retval = mozilla::dom::SystemGlobalEnumerate(cx, obj);
     return *_retval ? NS_OK : NS_ERROR_FAILURE;
 }
 
 /***************************************************************************/
 NS_IMETHODIMP
 BackstagePass::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
 {
-    const uint32_t count = 2;
-    *aCount = count;
-    nsIID** array;
-    *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
-    if (!array)
-        return NS_ERROR_OUT_OF_MEMORY;
+    *aCount = 2;
+    nsIID** array = static_cast<nsIID**>(moz_xmalloc(2 * sizeof(nsIID*)));
+    *aArray = array;
 
-    uint32_t index = 0;
-    nsIID* clone;
-#define PUSH_IID(id)                                                          \
-    clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ),           \
-                                                 sizeof(nsIID)));             \
-    if (!clone)                                                               \
-        goto oom;                                                             \
-    array[index++] = clone;
-
-    PUSH_IID(nsIXPCScriptable)
-    PUSH_IID(nsIScriptObjectPrincipal)
-#undef PUSH_IID
-
+    array[0] = NS_GET_IID(nsIXPCScriptable).Clone();
+    array[1] = NS_GET_IID(nsIScriptObjectPrincipal).Clone();
     return NS_OK;
-oom:
-    while (index)
-        free(array[--index]);
-    free(array);
-    *aArray = nullptr;
-    return NS_ERROR_OUT_OF_MEMORY;
 }
 
 NS_IMETHODIMP
 BackstagePass::GetScriptableHelper(nsIXPCScriptable** retval)
 {
     nsCOMPtr<nsIXPCScriptable> scriptable = this;
     scriptable.forget(retval);
     return NS_OK;
--- a/js/xpconnect/src/XPCWrappedJS.cpp
+++ b/js/xpconnect/src/XPCWrappedJS.cpp
@@ -615,18 +615,18 @@ nsXPCWrappedJS::CallMethod(uint16_t meth
     return GetClass()->CallMethod(this, methodIndex, info, params);
 }
 
 NS_IMETHODIMP
 nsXPCWrappedJS::GetInterfaceIID(nsIID** iid)
 {
     NS_PRECONDITION(iid, "bad param");
 
-    *iid = (nsIID*) nsMemory::Clone(&(GetIID()), sizeof(nsIID));
-    return *iid ? NS_OK : NS_ERROR_UNEXPECTED;
+    *iid = GetIID().Clone();
+    return NS_OK;
 }
 
 void
 nsXPCWrappedJS::SystemIsBeingShutDown()
 {
     // XXX It turns out that it is better to leak here then to do any Releases
     // and have them propagate into all sorts of mischief as the system is being
     // shutdown. This was learned the hard way :(
--- a/xpcom/base/nsIClassInfoImpl.h
+++ b/xpcom/base/nsIClassInfoImpl.h
@@ -142,18 +142,17 @@ private:
 NS_IMETHODIMP                                                                 \
 NS_CI_INTERFACE_GETTER_NAME(_class)(uint32_t *count, nsIID ***array)          \
 {                                                                             \
     *count = _c;                                                              \
     *array = (nsIID **)moz_xmalloc(sizeof (nsIID *) * _c);                \
     uint32_t i = 0;
 
 #define NS_CLASSINFO_HELPER_ENTRY(_interface)                                 \
-    (*array)[i++] = (nsIID*)nsMemory::Clone(&NS_GET_IID(_interface),          \
-                                            sizeof(nsIID));
+    (*array)[i++] = NS_GET_IID(_interface).Clone();                           \
 
 #define NS_CLASSINFO_HELPER_END                                               \
     MOZ_ASSERT(i == *count, "Incorrent number of entries");                   \
     return NS_OK;                                                             \
 }
 
 #define NS_IMPL_CI_INTERFACE_GETTER(aClass, ...)                              \
   static_assert(MOZ_ARG_COUNT(__VA_ARGS__) > 0,                               \
--- a/xpcom/base/nsID.cpp
+++ b/xpcom/base/nsID.cpp
@@ -124,8 +124,16 @@ nsID::ToProvidedString(char (&aDest)[NSI
   SprintfLiteral(aDest, gIDFormat,
                  m0, (uint32_t)m1, (uint32_t)m2,
                  (uint32_t)m3[0], (uint32_t)m3[1], (uint32_t)m3[2],
                  (uint32_t)m3[3], (uint32_t)m3[4], (uint32_t)m3[5],
                  (uint32_t)m3[6], (uint32_t)m3[7]);
 }
 
 #endif // XPCOM_GLUE_AVOID_NSPR
+
+nsID*
+nsID::Clone() const
+{
+  auto id = static_cast<nsID*>(moz_xmalloc(sizeof(nsID)));
+  *id = *this;
+  return id;
+}
--- a/xpcom/base/nsID.h
+++ b/xpcom/base/nsID.h
@@ -78,16 +78,19 @@ struct nsID
    * nsID string encoder. Builds a string in
    * {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} format, into a char[NSID_LENGTH]
    * buffer provided by the caller (for instance, on the stack).
    */
   void ToProvidedString(char (&aDest)[NSID_LENGTH]) const;
 
 #endif // XPCOM_GLUE_AVOID_NSPR
 
+  // Infallibly duplicate an nsID. Must be freed with free().
+  nsID* Clone() const;
+
   //@}
 };
 
 #ifndef XPCOM_GLUE_AVOID_NSPR
 /**
  * A stack helper class to convert a nsID to a string.  Useful
  * for printing nsIDs.  For example:
  *   nsID aID = ...;
--- a/xpcom/ds/nsSupportsPrimitives.cpp
+++ b/xpcom/ds/nsSupportsPrimitives.cpp
@@ -40,38 +40,28 @@ nsSupportsID::GetType(uint16_t* aType)
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSupportsID::GetData(nsID** aData)
 {
   NS_ASSERTION(aData, "Bad pointer");
 
-  if (mData) {
-    *aData = static_cast<nsID*>(nsMemory::Clone(mData, sizeof(nsID)));
-  } else {
-    *aData = nullptr;
-  }
-
+  *aData = mData ? mData->Clone() : nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSupportsID::SetData(const nsID* aData)
 {
   if (mData) {
     free(mData);
   }
 
-  if (aData) {
-    mData = static_cast<nsID*>(nsMemory::Clone(aData, sizeof(nsID)));
-  } else {
-    mData = nullptr;
-  }
-
+  mData = aData ? aData->Clone() : nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSupportsID::ToString(char** aResult)
 {
   NS_ASSERTION(aResult, "Bad pointer");
 
@@ -710,38 +700,28 @@ nsSupportsInterfacePointer::SetData(nsIS
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSupportsInterfacePointer::GetDataIID(nsID** aIID)
 {
   NS_ASSERTION(aIID, "Bad pointer");
 
-  if (mIID) {
-    *aIID = static_cast<nsID*>(nsMemory::Clone(mIID, sizeof(nsID)));
-  } else {
-    *aIID = nullptr;
-  }
-
+  *aIID = mIID ? mIID->Clone() : nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSupportsInterfacePointer::SetDataIID(const nsID* aIID)
 {
   if (mIID) {
     free(mIID);
   }
 
-  if (aIID) {
-    mIID = static_cast<nsID*>(nsMemory::Clone(aIID, sizeof(nsID)));
-  } else {
-    mIID = nullptr;
-  }
-
+  mIID = aIID ? aIID->Clone() : nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSupportsInterfacePointer::ToString(char** aResult)
 {
   NS_ASSERTION(aResult, "Bad pointer");
 
--- a/xpcom/ds/nsVariant.cpp
+++ b/xpcom/ds/nsVariant.cpp
@@ -246,18 +246,16 @@ CloneArray(uint16_t aInType, const nsIID
            uint32_t* aOutCount, void** aOutValue)
 {
   NS_ASSERTION(aInCount, "bad param");
   NS_ASSERTION(aInValue, "bad param");
   NS_ASSERTION(aOutType, "bad param");
   NS_ASSERTION(aOutCount, "bad param");
   NS_ASSERTION(aOutValue, "bad param");
 
-  uint32_t allocatedValueCount = 0;
-  nsresult rv = NS_OK;
   uint32_t i;
 
   // First we figure out the size of the elements for the new u.array.
 
   size_t elementSize;
   size_t allocSize;
 
   switch (aInType) {
@@ -373,53 +371,48 @@ CloneArray(uint16_t aInType, const nsIID
 
     // XXX We ASSUME that "array of nsID" means "array of pointers to nsID".
     case nsIDataType::VTYPE_ID: {
       nsID** inp  = (nsID**)aInValue;
       nsID** outp = (nsID**)*aOutValue;
       for (i = aInCount; i > 0; --i) {
         nsID* idp = *(inp++);
         if (idp) {
-          if (!(*(outp++) = (nsID*)nsMemory::Clone((char*)idp, sizeof(nsID)))) {
-            goto bad;
-          }
+          *(outp++) = idp->Clone();
         } else {
           *(outp++) = nullptr;
         }
-        allocatedValueCount++;
       }
       break;
     }
 
     case nsIDataType::VTYPE_CHAR_STR: {
       char** inp  = (char**)aInValue;
       char** outp = (char**)*aOutValue;
       for (i = aInCount; i > 0; i--) {
         char* str = *(inp++);
         if (str) {
           *(outp++) = moz_xstrdup(str);
         } else {
           *(outp++) = nullptr;
         }
-        allocatedValueCount++;
       }
       break;
     }
 
     case nsIDataType::VTYPE_WCHAR_STR: {
       char16_t** inp  = (char16_t**)aInValue;
       char16_t** outp = (char16_t**)*aOutValue;
       for (i = aInCount; i > 0; i--) {
         char16_t* str = *(inp++);
         if (str) {
           *(outp++) = NS_strdup(str);
         } else {
           *(outp++) = nullptr;
         }
-        allocatedValueCount++;
       }
       break;
     }
 
     // The rest are illegal.
     case nsIDataType::VTYPE_VOID:
     case nsIDataType::VTYPE_ARRAY:
     case nsIDataType::VTYPE_EMPTY_ARRAY:
@@ -433,28 +426,16 @@ CloneArray(uint16_t aInType, const nsIID
     default:
       NS_ERROR("bad type in array!");
       return NS_ERROR_CANNOT_CONVERT_DATA;
   }
 
   *aOutType = aInType;
   *aOutCount = aInCount;
   return NS_OK;
-
-bad:
-  if (*aOutValue) {
-    char** p = (char**)*aOutValue;
-    for (i = allocatedValueCount; i > 0; ++p, --i)
-      if (*p) {
-        free(*p);
-      }
-    free((char*)*aOutValue);
-    *aOutValue = nullptr;
-  }
-  return rv;
 }
 
 /***************************************************************************/
 
 #define TRIVIAL_DATA_CONVERTER(type_, member_, retval_)                       \
     if (mType == nsIDataType::type_) {                                        \
         *retval_ = u.member_;                                                 \
         return NS_OK;                                                         \
@@ -1157,20 +1138,17 @@ nsDiscriminatedUnion::ConvertToInterface
       break;
     case nsIDataType::VTYPE_INTERFACE_IS:
       piid = &u.iface.mInterfaceID;
       break;
     default:
       return NS_ERROR_CANNOT_CONVERT_DATA;
   }
 
-  *aIID = (nsIID*)nsMemory::Clone(piid, sizeof(nsIID));
-  if (!*aIID) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
+  *aIID = piid->Clone();
 
   if (u.iface.mInterfaceValue) {
     return u.iface.mInterfaceValue->QueryInterface(*piid, aInterface);
   }
 
   *aInterface = nullptr;
   return NS_OK;
 }
--- a/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
+++ b/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
@@ -407,17 +407,17 @@ ShimInterfaceInfo::GetName(char** aName)
 {
     *aName = ToNewCString(mName);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 ShimInterfaceInfo::GetInterfaceIID(nsIID** aIID)
 {
-    *aIID = static_cast<nsIID*> (nsMemory::Clone(&mIID, sizeof(mIID)));
+    *aIID = mIID.Clone();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 ShimInterfaceInfo::IsScriptable(bool* aRetVal)
 {
     // This class should pretend that the interface is scriptable because
     // that's what nsJSIID assumes.
--- a/xpcom/reflect/xptinfo/xptiInterfaceInfo.cpp
+++ b/xpcom/reflect/xptinfo/xptiInterfaceInfo.cpp
@@ -122,18 +122,18 @@ xptiInterfaceEntry::GetName(char **name)
     *name = moz_xstrdup(mName);
     return NS_OK;
 }
 
 nsresult
 xptiInterfaceEntry::GetIID(nsIID **iid)
 {
     // It is not necessary to Resolve because this info is read from manifest.
-    *iid = (nsIID*) nsMemory::Clone(&mIID, sizeof(nsIID));
-    return *iid ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+    *iid = mIID.Clone();
+    return NS_OK;
 }
 
 nsresult
 xptiInterfaceEntry::IsScriptable(bool* result)
 {
     // It is not necessary to Resolve because this info is read from manifest.
     *result = GetScriptableFlag();
     return NS_OK;