diff --git a/js/src/builtin/String.cpp b/js/src/builtin/String.cpp index f32f49c34caa..fcdd340d14eb 100644 --- a/js/src/builtin/String.cpp +++ b/js/src/builtin/String.cpp @@ -8,6 +8,7 @@ #include "mozilla/Attributes.h" #include "mozilla/CheckedInt.h" +#include "mozilla/Compiler.h" #include "mozilla/FloatingPoint.h" #if JS_HAS_INTL_API # include "mozilla/intl/String.h" @@ -544,7 +545,12 @@ template static inline void CopyChars(DestChar* destChars, const SrcChar* srcChars, size_t length) { if constexpr (std::is_same_v) { +#if MOZ_IS_GCC + // Directly call memcpy to work around bug 1863131. + memcpy(destChars, srcChars, length * sizeof(DestChar)); +#else PodCopy(destChars, srcChars, length); +#endif } else { for (size_t i = 0; i < length; i++) { destChars[i] = srcChars[i]; diff --git a/mfbt/PodOperations.h b/mfbt/PodOperations.h index cd6ad67cf4ad..3c10090eede0 100644 --- a/mfbt/PodOperations.h +++ b/mfbt/PodOperations.h @@ -96,6 +96,19 @@ static MOZ_ALWAYS_INLINE void PodCopy(T* aDst, const T* aSrc, size_t aNElem) { MOZ_ASSERT(aDst + aNElem <= aSrc || aSrc + aNElem <= aDst, "destination and source must not overlap"); +// Linux memcpy for small sizes seems slower than on other +// platforms. So we use a loop for small sizes there only. +// +// See Bug 1967062 for details. +#if defined(XP_LINUX) + if (aNElem < 128) { + for (const T* srcend = aSrc + aNElem; aSrc < srcend; aSrc++, aDst++) { + *aDst = *aSrc; + } + return; + } +#endif + memcpy(aDst, aSrc, aNElem * sizeof(T)); }