commit a2f7844ff12ff81ed6ae02c38f161dcbb6603357
parent d5bae296c2f3b89bfa43772ad002509e4da05acd
Author: serge-sans-paille <sguelton@mozilla.com>
Date: Fri, 3 Oct 2025 09:51:38 +0000
Bug 1991860 - Modernize mfbt/EndianUtils.h r=emilio,necko-reviewers,media-playback-reviewers,padenot
- remove unused headers
- __builtin_bswap* is always available for supported compilers
- do not use union for type punning
Differential Revision: https://phabricator.services.mozilla.com/D267305
Diffstat:
19 files changed, 27 insertions(+), 103 deletions(-)
diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -33,7 +33,6 @@
#include "mozilla/CheckedInt.h"
#include "mozilla/CycleCollectedJSRuntime.h"
#include "mozilla/DebugOnly.h"
-#include "mozilla/EndianUtils.h"
#include "mozilla/FilterInstance.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/GeckoBindings.h"
diff --git a/dom/canvas/WebGLContextGL.cpp b/dom/canvas/WebGLContextGL.cpp
@@ -29,7 +29,6 @@
#include "gfxUtils.h"
#include "jsfriendapi.h"
#include "mozilla/DebugOnly.h"
-#include "mozilla/EndianUtils.h"
#include "mozilla/RefPtr.h"
#include "mozilla/StaticPrefs_webgl.h"
#include "mozilla/dom/BindingUtils.h"
diff --git a/dom/canvas/WebGLContextTextures.cpp b/dom/canvas/WebGLContextTextures.cpp
@@ -24,7 +24,6 @@
#include "gfxUtils.h"
#include "jsfriendapi.h"
#include "mozilla/DebugOnly.h"
-#include "mozilla/EndianUtils.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/ImageData.h"
#include "nsContentUtils.h"
diff --git a/dom/media/ByteWriter.h b/dom/media/ByteWriter.h
@@ -5,7 +5,6 @@
#ifndef BYTE_WRITER_H_
#define BYTE_WRITER_H_
-#include "mozilla/EndianUtils.h"
#include "nsTArray.h"
namespace mozilla {
diff --git a/dom/media/WavDumper.h b/dom/media/WavDumper.h
@@ -9,6 +9,7 @@
# include <ByteWriter.h>
# include <mozilla/Atomics.h>
# include <mozilla/DebugOnly.h>
+# include <mozilla/EndianUtils.h>
# include <mozilla/Sprintf.h>
# include <mozilla/Unused.h>
# include <nsString.h>
diff --git a/dom/media/mediasource/ContainerParser.cpp b/dom/media/mediasource/ContainerParser.cpp
@@ -17,7 +17,6 @@
#include "SampleIterator.h"
#include "SourceBufferResource.h"
#include "WebMBufferedParser.h"
-#include "mozilla/EndianUtils.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/Logging.h"
diff --git a/dom/media/mp4/Box.h b/dom/media/mp4/Box.h
@@ -12,7 +12,6 @@
#include "AtomType.h"
#include "BufferReader.h"
#include "MediaResource.h"
-#include "mozilla/EndianUtils.h"
#include "nsTArray.h"
namespace mozilla {
diff --git a/dom/media/mp4/MP4Metadata.cpp b/dom/media/mp4/MP4Metadata.cpp
@@ -13,7 +13,6 @@
#include "MoofParser.h"
#include "VideoUtils.h"
#include "mozilla/Assertions.h"
-#include "mozilla/EndianUtils.h"
#include "mozilla/Logging.h"
#include "mozilla/RefPtr.h"
#include "mozilla/UniquePtr.h"
diff --git a/dom/media/webm/WebMDemuxer.cpp b/dom/media/webm/WebMDemuxer.cpp
@@ -24,7 +24,6 @@
#include "XiphExtradata.h"
#include "gfx2DGlue.h"
#include "gfxUtils.h"
-#include "mozilla/EndianUtils.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/Maybe.h"
#include "mozilla/SharedThreadPool.h"
diff --git a/image/decoders/icon/gtk/nsIconChannel.cpp b/image/decoders/icon/gtk/nsIconChannel.cpp
@@ -14,7 +14,6 @@
#include "nsIIconURI.h"
#include "mozilla/gfx/DataSurfaceHelpers.h"
#include "mozilla/DebugOnly.h"
-#include "mozilla/EndianUtils.h"
#include "mozilla/NullPrincipal.h"
#include "mozilla/LookAndFeel.h"
#include "mozilla/CheckedInt.h"
diff --git a/image/decoders/icon/mac/nsIconChannelCocoa.mm b/image/decoders/icon/mac/nsIconChannelCocoa.mm
@@ -7,7 +7,6 @@
#include "nsContentUtils.h"
#include "nsIconChannel.h"
#include "mozilla/BasePrincipal.h"
-#include "mozilla/EndianUtils.h"
#include "nsComponentManagerUtils.h"
#include "nsIIconURI.h"
#include "nsIInputStream.h"
diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h
@@ -7,7 +7,6 @@
#ifndef jit_MacroAssembler_h
#define jit_MacroAssembler_h
-#include "mozilla/EndianUtils.h"
#include "mozilla/MacroForEach.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/Maybe.h"
diff --git a/js/src/wasm/WasmJS.cpp b/js/src/wasm/WasmJS.cpp
@@ -18,7 +18,6 @@
#include "wasm/WasmJS.h"
-#include "mozilla/EndianUtils.h"
#include "mozilla/Maybe.h"
#include <algorithm>
diff --git a/js/xpconnect/loader/ScriptPreloader-inl.h b/js/xpconnect/loader/ScriptPreloader-inl.h
@@ -8,7 +8,6 @@
#include "mozilla/Attributes.h"
#include "mozilla/Assertions.h"
-#include "mozilla/EndianUtils.h"
#include "mozilla/EnumSet.h"
#include "mozilla/Range.h"
#include "mozilla/ResultExtensions.h"
diff --git a/mfbt/EndianUtils.h b/mfbt/EndianUtils.h
@@ -67,7 +67,6 @@
#define mozilla_EndianUtils_h
#include "mozilla/Assertions.h"
-#include "mozilla/Attributes.h"
#include "mozilla/DebugOnly.h"
#include <stdint.h>
@@ -83,6 +82,8 @@
/*
* Our supported compilers provide architecture-independent macros for this.
* Yes, there are more than two values for __BYTE_ORDER__.
+ *
+ * FIXME: use std::endian once we move to C++20
*/
#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
defined(__ORDER_BIG_ENDIAN__)
@@ -99,72 +100,22 @@
# error "Don't know how to determine endianness"
#endif
-#if defined(__clang__)
-# if __has_builtin(__builtin_bswap16)
-# define MOZ_HAVE_BUILTIN_BYTESWAP16 __builtin_bswap16
-# endif
-#elif defined(__GNUC__)
-# define MOZ_HAVE_BUILTIN_BYTESWAP16 __builtin_bswap16
-#elif defined(_MSC_VER)
-# define MOZ_HAVE_BUILTIN_BYTESWAP16 _byteswap_ushort
-#endif
-
namespace mozilla {
-namespace detail {
-
-/*
- * We need wrappers here because free functions with default template
- * arguments and/or partial specialization of function templates are not
- * supported by all the compilers we use.
+/* FIXME: move to std::byteswap with C++23
*/
-template <typename T, size_t Size = sizeof(T)>
-struct Swapper;
-
template <typename T>
-struct Swapper<T, 2> {
- static T swap(T aValue) {
-#if defined(MOZ_HAVE_BUILTIN_BYTESWAP16)
- return MOZ_HAVE_BUILTIN_BYTESWAP16(aValue);
-#else
- return T(((aValue & 0x00ff) << 8) | ((aValue & 0xff00) >> 8));
-#endif
+T byteswap(T n) {
+ if constexpr (sizeof(T) == 2) {
+ return __builtin_bswap16(n);
+ } else if constexpr (sizeof(T) == 4) {
+ return __builtin_bswap32(n);
+ } else if constexpr (sizeof(T) == 8) {
+ return __builtin_bswap64(n);
}
-};
+}
-template <typename T>
-struct Swapper<T, 4> {
- static T swap(T aValue) {
-#if defined(__clang__) || defined(__GNUC__)
- return T(__builtin_bswap32(aValue));
-#elif defined(_MSC_VER)
- return T(_byteswap_ulong(aValue));
-#else
- return T(((aValue & 0x000000ffU) << 24) | ((aValue & 0x0000ff00U) << 8) |
- ((aValue & 0x00ff0000U) >> 8) | ((aValue & 0xff000000U) >> 24));
-#endif
- }
-};
-
-template <typename T>
-struct Swapper<T, 8> {
- static inline T swap(T aValue) {
-#if defined(__clang__) || defined(__GNUC__)
- return T(__builtin_bswap64(aValue));
-#elif defined(_MSC_VER)
- return T(_byteswap_uint64(aValue));
-#else
- return T(((aValue & 0x00000000000000ffULL) << 56) |
- ((aValue & 0x000000000000ff00ULL) << 40) |
- ((aValue & 0x0000000000ff0000ULL) << 24) |
- ((aValue & 0x00000000ff000000ULL) << 8) |
- ((aValue & 0x000000ff00000000ULL) >> 8) |
- ((aValue & 0x0000ff0000000000ULL) >> 24) |
- ((aValue & 0x00ff000000000000ULL) >> 40) |
- ((aValue & 0xff00000000000000ULL) >> 56));
-#endif
- }
-};
+namespace detail {
enum Endianness { Little, Big };
@@ -200,10 +151,10 @@ class EndianUtils {
*/
template <Endianness SourceEndian, Endianness DestEndian, typename T>
static inline T maybeSwap(T aValue) {
- if (SourceEndian == DestEndian) {
+ if constexpr (SourceEndian == DestEndian) {
return aValue;
}
- return Swapper<T>::swap(aValue);
+ return byteswap(aValue);
}
/**
@@ -214,11 +165,11 @@ class EndianUtils {
static inline void maybeSwapInPlace(T* aPtr, size_t aCount) {
assertAligned(aPtr);
- if (SourceEndian == DestEndian) {
+ if constexpr (SourceEndian == DestEndian) {
return;
}
for (size_t i = 0; i < aCount; i++) {
- aPtr[i] = Swapper<T>::swap(aPtr[i]);
+ aPtr[i] = byteswap(aPtr[i]);
}
}
@@ -231,19 +182,15 @@ class EndianUtils {
assertNoOverlap(aDest, aSrc, aCount * sizeof(T));
assertAligned(aSrc);
- if (SourceEndian == DestEndian) {
+ if constexpr (SourceEndian == DestEndian) {
memcpy(aDest, aSrc, aCount * sizeof(T));
return;
}
uint8_t* byteDestPtr = static_cast<uint8_t*>(aDest);
for (size_t i = 0; i < aCount; ++i) {
- union {
- T mVal;
- uint8_t mBuffer[sizeof(T)];
- } u;
- u.mVal = maybeSwap<SourceEndian, DestEndian>(aSrc[i]);
- memcpy(byteDestPtr, u.mBuffer, sizeof(T));
+ const T Val = maybeSwap<SourceEndian, DestEndian>(aSrc[i]);
+ memcpy(byteDestPtr, static_cast<const void*>(&Val), sizeof(T));
byteDestPtr += sizeof(T);
}
}
@@ -257,19 +204,16 @@ class EndianUtils {
assertNoOverlap(aDest, aSrc, aCount * sizeof(T));
assertAligned(aDest);
- if (SourceEndian == DestEndian) {
+ if constexpr (SourceEndian == DestEndian) {
memcpy(aDest, aSrc, aCount * sizeof(T));
return;
}
const uint8_t* byteSrcPtr = static_cast<const uint8_t*>(aSrc);
for (size_t i = 0; i < aCount; ++i) {
- union {
- T mVal;
- uint8_t mBuffer[sizeof(T)];
- } u;
- memcpy(u.mBuffer, byteSrcPtr, sizeof(T));
- aDest[i] = maybeSwap<SourceEndian, DestEndian>(u.mVal);
+ T Val;
+ memcpy(static_cast<void*>(&Val), byteSrcPtr, sizeof(T));
+ aDest[i] = maybeSwap<SourceEndian, DestEndian>(Val);
byteSrcPtr += sizeof(T);
}
}
@@ -512,12 +456,9 @@ class Endian : private EndianUtils {
*/
template <typename T>
static T read(const void* aPtr) {
- union {
- T mVal;
- uint8_t mBuffer[sizeof(T)];
- } u;
- memcpy(u.mBuffer, aPtr, sizeof(T));
- return maybeSwap<ThisEndian, MOZ_NATIVE_ENDIANNESS>(u.mVal);
+ T Val;
+ memcpy(static_cast<void*>(&Val), aPtr, sizeof(T));
+ return maybeSwap<ThisEndian, MOZ_NATIVE_ENDIANNESS>(Val);
}
/**
diff --git a/mozglue/misc/SIMD_avx2.cpp b/mozglue/misc/SIMD_avx2.cpp
@@ -18,8 +18,6 @@
# include <stdint.h>
# include <type_traits>
-# include "mozilla/EndianUtils.h"
-
namespace mozilla {
const __m256i* Cast256(uintptr_t ptr) {
diff --git a/netwerk/base/nsUDPSocket.cpp b/netwerk/base/nsUDPSocket.cpp
@@ -6,7 +6,6 @@
#include "Predictor.h"
#include "mozilla/Attributes.h"
#include "mozilla/Components.h"
-#include "mozilla/EndianUtils.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/HoldDropJSObjects.h"
#include "mozilla/glean/NetwerkMetrics.h"
diff --git a/netwerk/dns/DNSPacket.cpp b/netwerk/dns/DNSPacket.cpp
@@ -5,7 +5,6 @@
#include "DNSPacket.h"
#include "DNS.h"
-#include "mozilla/EndianUtils.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/StaticPrefs_network.h"
// Put DNSLogging.h at the end to avoid LOG being overwritten by other headers.
diff --git a/xpcom/string/nsUTF8Utils.h b/xpcom/string/nsUTF8Utils.h
@@ -15,7 +15,6 @@
#include <type_traits>
#include "mozilla/Assertions.h"
-#include "mozilla/EndianUtils.h"
#include "nsCharTraits.h"