Bug 1402247 part 8 - Remove LossyConvertEncoding8to16 and LossyConvertEncoding16to8.
MozReview-Commit-ID: Jjxjh7uw6Ng
--- a/dom/base/nsTextFragment.cpp
+++ b/dom/base/nsTextFragment.cpp
@@ -11,17 +11,16 @@
*/
#include "nsTextFragment.h"
#include "nsCRT.h"
#include "nsReadableUtils.h"
#include "nsMemory.h"
#include "nsBidiUtils.h"
#include "nsUnicharUtils.h"
-#include "nsUTF8Utils.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/SSE.h"
#include "nsTextFragmentImpl.h"
#include <algorithm>
#define TEXTFRAG_WHITE_AFTER_NEWLINE 50
#define TEXTFRAG_MAX_NEWLINES 7
@@ -314,18 +313,17 @@ nsTextFragment::SetTo(const char16_t* aB
} else {
// Use 1 byte storage because we can
char* buff = static_cast<char*>(malloc(aLength));
if (!buff) {
return false;
}
// Copy data
- LossyConvertEncoding16to8 converter(buff);
- copy_string(aBuffer, aBuffer+aLength, converter);
+ LossyConvertUTF16toLatin1(MakeSpan(aBuffer, aLength), MakeSpan(buff, aLength));
m1b = buff;
mState.mIs2b = false;
}
// Setup our fields
mState.mInHeap = true;
mState.mLength = aLength;
@@ -346,19 +344,17 @@ nsTextFragment::CopyTo(char16_t *aDest,
aCount = mState.mLength - aOffset;
}
if (aCount != 0) {
if (mState.mIs2b) {
memcpy(aDest, Get2b() + aOffset, sizeof(char16_t) * aCount);
} else {
const char *cp = m1b + aOffset;
- const char *end = cp + aCount;
- LossyConvertEncoding8to16 converter(aDest);
- copy_string(cp, end, converter);
+ ConvertLatin1toUTF16(MakeSpan(cp, aCount), MakeSpan(aDest, aCount));
}
}
}
bool
nsTextFragment::Append(const char16_t* aBuffer, uint32_t aLength,
bool aUpdateBidi, bool aForce2b)
{
@@ -431,18 +427,17 @@ nsTextFragment::Append(const char16_t* a
// all to 2-byte
nsStringBuffer* buff = nsStringBuffer::Alloc(size).take();
if (!buff) {
return false;
}
// Copy data into buff
char16_t* data = static_cast<char16_t*>(buff->Data());
- LossyConvertEncoding8to16 converter(data);
- copy_string(m1b, m1b+mState.mLength, converter);
+ ConvertLatin1toUTF16(MakeSpan(m1b, mState.mLength), MakeSpan(data, mState.mLength));
memcpy(data + mState.mLength, aBuffer, aLength * sizeof(char16_t));
mState.mLength += aLength;
mState.mIs2b = true;
if (mState.mInHeap) {
free(const_cast<char*>(m1b));
}
@@ -474,18 +469,17 @@ nsTextFragment::Append(const char16_t* a
return false;
}
memcpy(buff, m1b, mState.mLength);
mState.mInHeap = true;
}
// Copy aBuffer into buff.
- LossyConvertEncoding16to8 converter(buff + mState.mLength);
- copy_string(aBuffer, aBuffer + aLength, converter);
+ LossyConvertUTF16toLatin1(MakeSpan(aBuffer, aLength), MakeSpan(buff + mState.mLength, aLength));
m1b = buff;
mState.mLength += aLength;
return true;
}
/* virtual */ size_t
--- a/parser/html/nsHtml5String.cpp
+++ b/parser/html/nsHtml5String.cpp
@@ -164,18 +164,17 @@ nsHtml5String::FromLiteral(const char* a
// nsAttrValue::GetStringBuffer, so that it doesn't need to reallocate and
// copy.
RefPtr<nsStringBuffer> buffer(
nsStringBuffer::Alloc((length + 1) * sizeof(char16_t)));
if (!buffer) {
MOZ_CRASH("Out of memory.");
}
char16_t* data = reinterpret_cast<char16_t*>(buffer->Data());
- LossyConvertEncoding8to16 converter(data);
- converter.write(aLiteral, length);
+ ConvertLatin1toUTF16(MakeSpan(aLiteral, length), MakeSpan(data, length));
data[length] = 0;
return nsHtml5String(reinterpret_cast<uintptr_t>(buffer.forget().take()) | eStringBuffer);
}
// static
nsHtml5String
nsHtml5String::FromString(const nsAString& aString)
{
--- a/xpcom/string/moz.build
+++ b/xpcom/string/moz.build
@@ -44,26 +44,16 @@ UNIFIED_SOURCES += [
'nsStringComparator.cpp',
'nsStringObsolete.cpp',
'nsSubstring.cpp',
'nsTextFormatter.cpp',
'nsTSubstringTuple.cpp',
'precompiled_templates.cpp',
]
-# Are we targeting x86 or x86-64? If so, compile the SSE2 functions for
-# nsUTF8Utils.cpp and nsReadableUtils.cpp.
-if CONFIG['INTEL_ARCHITECTURE']:
- SOURCES += ['nsUTF8UtilsSSE2.cpp']
- SOURCES['nsUTF8UtilsSSE2.cpp'].flags += CONFIG['SSE2_FLAGS']
-
-if CONFIG['BUILD_ARM_NEON'] or CONFIG['CPU_ARCH'] == 'aarch64':
- SOURCES += ['nsUTF8UtilsNEON.cpp']
- SOURCES['nsUTF8UtilsNEON.cpp'].flags += CONFIG['NEON_FLAGS']
-
# MSVC 2017 has a bug that incorrectly generates C5037 warning which
# hits the template string code. We need to disable this warning as a
# workaround. See https://developercommunity.visualstudio.com/
# content/problem/81223/incorrect-error-c5037-with-permissive.html
if CONFIG['CC_TYPE'] in ('msvc', 'clang-cl'):
CXXFLAGS += ['-wd5037']
FINAL_LIBRARY = 'xul'
--- a/xpcom/string/nsUTF8Utils.h
+++ b/xpcom/string/nsUTF8Utils.h
@@ -6,20 +6,18 @@
#ifndef nsUTF8Utils_h_
#define nsUTF8Utils_h_
// This file may be used in two ways: if MOZILLA_INTERNAL_API is defined, this
// file will provide signatures for the Mozilla abstract string types. It will
// use XPCOM assertion/debugging macros, etc.
#include "nscore.h"
-#include "mozilla/arm.h"
#include "mozilla/Assertions.h"
#include "mozilla/EndianUtils.h"
-#include "mozilla/SSE.h"
#include "mozilla/TypeTraits.h"
#include "nsCharTraits.h"
#ifdef MOZILLA_INTERNAL_API
#define UTF8UTILS_WARNING(msg) NS_WARNING(msg)
#else
#define UTF8UTILS_WARNING(msg)
@@ -273,130 +271,16 @@ public:
*aBuffer = p;
return 0xFFFD;
}
MOZ_ASSERT_UNREACHABLE("Impossible UCS-2 character value.");
}
};
-#ifdef MOZILLA_INTERNAL_API
-/**
- * A character sink that performs a |reinterpret_cast|-style conversion
- * from char to char16_t.
- */
-class LossyConvertEncoding8to16
-{
-public:
- typedef char value_type;
- typedef char input_type;
- typedef char16_t output_type;
-
-public:
- explicit LossyConvertEncoding8to16(char16_t* aDestination) :
- mDestination(aDestination)
- {
- }
-
- void
- write(const char* aSource, uint32_t aSourceLength)
- {
-#ifdef MOZILLA_MAY_SUPPORT_SSE2
- if (mozilla::supports_sse2()) {
- write_sse2(aSource, aSourceLength);
- return;
- }
-#endif
-#if defined(MOZILLA_MAY_SUPPORT_NEON) && defined(MOZ_LITTLE_ENDIAN)
- if (mozilla::supports_neon()) {
- write_neon(aSource, aSourceLength);
- return;
- }
-#endif
- const char* done_writing = aSource + aSourceLength;
- while (aSource < done_writing) {
- *mDestination++ = (char16_t)(unsigned char)(*aSource++);
- }
- }
-
- void
- write_sse2(const char* aSource, uint32_t aSourceLength);
-#if defined(MOZILLA_MAY_SUPPORT_NEON) && defined(MOZ_LITTLE_ENDIAN)
- void
- write_neon(const char* aSource, uint32_t aSourceLength);
-#endif
-
- void
- write_terminator()
- {
- *mDestination = (char16_t)(0);
- }
-
-private:
- char16_t* mDestination;
-};
-
-/**
- * A character sink that performs a |reinterpret_cast|-style conversion
- * from char16_t to char.
- */
-class LossyConvertEncoding16to8
-{
-public:
- typedef char16_t value_type;
- typedef char16_t input_type;
- typedef char output_type;
-
- explicit LossyConvertEncoding16to8(char* aDestination)
- : mDestination(aDestination)
- {
- }
-
- void
- write(const char16_t* aSource, uint32_t aSourceLength)
- {
-#ifdef MOZILLA_MAY_SUPPORT_SSE2
- if (mozilla::supports_sse2()) {
- write_sse2(aSource, aSourceLength);
- return;
- }
-#endif
-#if defined(MOZILLA_MAY_SUPPORT_NEON) && defined(MOZ_LITTLE_ENDIAN)
- if (mozilla::supports_neon()) {
- write_neon(aSource, aSourceLength);
- return;
- }
-#endif
- const char16_t* done_writing = aSource + aSourceLength;
- while (aSource < done_writing) {
- *mDestination++ = (char)(*aSource++);
- }
- }
-
-#ifdef MOZILLA_MAY_SUPPORT_SSE2
- void
- write_sse2(const char16_t* aSource, uint32_t aSourceLength);
-#endif
-#if defined(MOZILLA_MAY_SUPPORT_NEON) && defined(MOZ_LITTLE_ENDIAN)
- void
- write_neon(const char16_t* aSource, uint32_t aSourceLength);
-#endif
-
- void
- write_terminator()
- {
- *mDestination = '\0';
- }
-
-private:
- char* mDestination;
-};
-#endif // MOZILLA_INTERNAL_API
-
-
template<typename Char, typename UnsignedT>
inline UnsignedT
RewindToPriorUTF8Codepoint(const Char* utf8Chars, UnsignedT index)
{
static_assert(mozilla::IsSame<Char, char>::value ||
mozilla::IsSame<Char, unsigned char>::value ||
mozilla::IsSame<Char, signed char>::value,
"UTF-8 data must be in 8-bit units");
deleted file mode 100644
--- a/xpcom/string/nsUTF8UtilsNEON.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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 "nscore.h"
-#include "nsAlgorithm.h"
-#include "nsUTF8Utils.h"
-
-#include <arm_neon.h>
-
-void
-LossyConvertEncoding16to8::write_neon(const char16_t* aSource,
- uint32_t aSourceLength)
-{
- char* dest = mDestination;
-
- // Align source to a 16-byte boundary and destination to 8-bytes boundary.
- uint32_t i = 0;
- while (((reinterpret_cast<uintptr_t>(aSource + i) & 0xf) ||
- (reinterpret_cast<uintptr_t>(dest + i) & 0x7)) &&
- i < aSourceLength) {
- dest[i] = static_cast<unsigned char>(aSource[i]);
- i++;
- }
-
- while ((reinterpret_cast<uintptr_t>(dest + i) & 0xf) &&
- aSourceLength - i > 7) {
- // source is aligned, but destination isn't aligned by 16-byte yet
- uint16x8_t s =
- vld1q_u16(reinterpret_cast<const uint16_t*>(
- __builtin_assume_aligned(aSource + i, 16)));
- vst1_u8(reinterpret_cast<uint8_t*>(
- __builtin_assume_aligned(dest + i, 8)),
- vmovn_u16(s));
- i += 8;
- }
-
- // Align source and destination to a 16-byte boundary.
- while (aSourceLength - i > 15) {
- uint16x8_t low =
- vld1q_u16(reinterpret_cast<const uint16_t*>(
- __builtin_assume_aligned(aSource + i, 16)));
- uint16x8_t high =
- vld1q_u16(reinterpret_cast<const uint16_t*>(
- __builtin_assume_aligned(aSource + i + 8, 16)));
- vst1q_u8(reinterpret_cast<uint8_t*>(
- __builtin_assume_aligned(dest + i, 16)),
- vcombine_u8(vmovn_u16(low), vmovn_u16(high)));
- i += 16;
- }
-
- if (aSourceLength - i > 7) {
- uint16x8_t s = vld1q_u16(reinterpret_cast<const uint16_t*>(
- __builtin_assume_aligned(aSource + i, 16)));
- vst1_u8(reinterpret_cast<uint8_t*>(
- __builtin_assume_aligned(dest + i, 8)),
- vmovn_u16(s));
- i += 8;
- }
-
- // Finish up the rest.
- for (; i < aSourceLength; ++i) {
- dest[i] = static_cast<unsigned char>(aSource[i]);
- }
-
- mDestination += i;
-}
-
-void
-LossyConvertEncoding8to16::write_neon(const char* aSource,
- uint32_t aSourceLength)
-{
- char16_t* dest = mDestination;
-
- // Align source to a 8-byte boundary and destination to 16-bytes boundary.
- uint32_t i = 0;
- while (((reinterpret_cast<uintptr_t>(aSource + i) & 0x7) ||
- (reinterpret_cast<uintptr_t>(dest + i) & 0xf)) &&
- i < aSourceLength) {
- dest[i] = static_cast<unsigned char>(aSource[i]);
- i++;
- }
-
- if ((uintptr_t(aSource + i) & 0xf) && aSourceLength - i > 7) {
- // destination is aligned, but source isn't aligned by 16-byte yet
- uint8x8_t s =
- vld1_u8(reinterpret_cast<const uint8_t*>(
- __builtin_assume_aligned(aSource + i, 8)));
- vst1q_u16(reinterpret_cast<uint16_t*>(
- __builtin_assume_aligned(dest + i, 16)),
- vmovl_u8(s));
- i += 8;
- }
-
- // Align source and destination to a 16-byte boundary.
- while (aSourceLength - i > 15) {
- uint8x16_t s =
- vld1q_u8(reinterpret_cast<const uint8_t*>(
- __builtin_assume_aligned(aSource + i, 16)));
- uint16x8_t low = vmovl_u8(vget_low_u8(s));
- uint16x8_t high = vmovl_u8(vget_high_u8(s));
- vst1q_u16(reinterpret_cast<uint16_t*>(
- __builtin_assume_aligned(dest + i, 16)),
- low);
- vst1q_u16(reinterpret_cast<uint16_t*>(
- __builtin_assume_aligned(dest + i + 8, 16)),
- high);
- i += 16;
- }
-
- if (aSourceLength - i > 7) {
- uint8x8_t s =
- vld1_u8(reinterpret_cast<const uint8_t*>(
- __builtin_assume_aligned(aSource + i, 8)));
- vst1q_u16(reinterpret_cast<uint16_t*>(
- __builtin_assume_aligned(dest + i, 16)),
- vmovl_u8(s));
- i += 8;
- }
-
- // Finish up whatever's left.
- for (; i < aSourceLength; ++i) {
- dest[i] = static_cast<unsigned char>(aSource[i]);
- }
-
- mDestination += i;
-}
deleted file mode 100644
--- a/xpcom/string/nsUTF8UtilsSSE2.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-/* 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 "nscore.h"
-#include "nsAlgorithm.h"
-#include <emmintrin.h>
-#include <nsUTF8Utils.h>
-
-void
-LossyConvertEncoding16to8::write_sse2(const char16_t* aSource,
- uint32_t aSourceLength)
-{
- char* dest = mDestination;
-
- // Align source to a 16-byte boundary.
- uint32_t i = 0;
- uint32_t alignLen =
- XPCOM_MIN<uint32_t>(aSourceLength,
- uint32_t(-NS_PTR_TO_INT32(aSource) & 0xf) / sizeof(char16_t));
- for (; i < alignLen; ++i) {
- dest[i] = static_cast<unsigned char>(aSource[i]);
- }
-
- // Walk 64 bytes (four XMM registers) at a time.
- __m128i vectmask = _mm_set1_epi16(0x00ff);
- for (; aSourceLength - i > 31; i += 32) {
- __m128i source1 = _mm_load_si128(reinterpret_cast<const __m128i*>(aSource + i));
- source1 = _mm_and_si128(source1, vectmask);
-
- __m128i source2 = _mm_load_si128(reinterpret_cast<const __m128i*>(aSource + i + 8));
- source2 = _mm_and_si128(source2, vectmask);
-
- __m128i source3 = _mm_load_si128(reinterpret_cast<const __m128i*>(aSource + i + 16));
- source3 = _mm_and_si128(source3, vectmask);
-
- __m128i source4 = _mm_load_si128(reinterpret_cast<const __m128i*>(aSource + i + 24));
- source4 = _mm_and_si128(source4, vectmask);
-
-
- // Pack the source data. SSE2 views this as a saturating uint16_t to
- // uint8_t conversion, but since we masked off the high-order byte of every
- // uint16_t, we're really just grabbing the low-order bytes of source1 and
- // source2.
- __m128i packed1 = _mm_packus_epi16(source1, source2);
- __m128i packed2 = _mm_packus_epi16(source3, source4);
-
- // This store needs to be unaligned since there's no guarantee that the
- // alignment we did above for the source will align the destination.
- _mm_storeu_si128(reinterpret_cast<__m128i*>(dest + i), packed1);
- _mm_storeu_si128(reinterpret_cast<__m128i*>(dest + i + 16), packed2);
- }
-
- // Finish up the rest.
- for (; i < aSourceLength; ++i) {
- dest[i] = static_cast<unsigned char>(aSource[i]);
- }
-
- mDestination += i;
-}
-
-void
-LossyConvertEncoding8to16::write_sse2(const char* aSource,
- uint32_t aSourceLength)
-{
- char16_t* dest = mDestination;
-
- // Align source to a 16-byte boundary. We choose to align source rather than
- // dest because we'd rather have our loads than our stores be fast. You have
- // to wait for a load to complete, but you can keep on moving after issuing a
- // store.
- uint32_t i = 0;
- uint32_t alignLen = XPCOM_MIN(aSourceLength,
- uint32_t(-NS_PTR_TO_INT32(aSource) & 0xf));
- for (; i < alignLen; ++i) {
- dest[i] = static_cast<unsigned char>(aSource[i]);
- }
-
- // Walk 32 bytes (two XMM registers) at a time.
- for (; aSourceLength - i > 31; i += 32) {
- __m128i source1 = _mm_load_si128(reinterpret_cast<const __m128i*>(aSource + i));
- __m128i source2 = _mm_load_si128(reinterpret_cast<const __m128i*>(aSource + i + 16));
-
- // Interleave 0s in with the bytes of source to create lo and hi.
- __m128i lo1 = _mm_unpacklo_epi8(source1, _mm_setzero_si128());
- __m128i hi1 = _mm_unpackhi_epi8(source1, _mm_setzero_si128());
- __m128i lo2 = _mm_unpacklo_epi8(source2, _mm_setzero_si128());
- __m128i hi2 = _mm_unpackhi_epi8(source2, _mm_setzero_si128());
-
- // store lo and hi into dest.
- _mm_storeu_si128(reinterpret_cast<__m128i*>(dest + i), lo1);
- _mm_storeu_si128(reinterpret_cast<__m128i*>(dest + i + 8), hi1);
- _mm_storeu_si128(reinterpret_cast<__m128i*>(dest + i + 16), lo2);
- _mm_storeu_si128(reinterpret_cast<__m128i*>(dest + i + 24), hi2);
- }
-
- // Finish up whatever's left.
- for (; i < aSourceLength; ++i) {
- dest[i] = static_cast<unsigned char>(aSource[i]);
- }
-
- mDestination += i;
-}