Modified: trunk/Source/WTF/ChangeLog (153685 => 153686)
--- trunk/Source/WTF/ChangeLog 2013-08-03 03:09:25 UTC (rev 153685)
+++ trunk/Source/WTF/ChangeLog 2013-08-03 03:33:25 UTC (rev 153686)
@@ -1,3 +1,32 @@
+2013-08-02 Benjamin Poulain <[email protected]>
+
+ Remove a bunch of redundant checks for empty string in StringImpl
+ https://bugs.webkit.org/show_bug.cgi?id=118768
+
+ Reviewed by Ryosuke Niwa.
+
+ The first thing done by createUninitialized() is check if the length passed
+ is zero. Internally, there are many cases for which we know the check will never succeed.
+
+ Clang is usually really smart for those kind of things, but there are a few cases where
+ the condition to avoid returning empty() is not simply a check for the length.
+ This patch adds an internal initializer to deal with that.
+
+ * wtf/text/StringImpl.cpp:
+ (WTF::StringImpl::createUninitializedInternal):
+ (WTF::StringImpl::createUninitializedInternalNonEmpty):
+ (WTF::StringImpl::createInternal): Create internal has a special case for null pointer
+ for the characters. The test also check length, the second check for length cannot fail.
+ (WTF::StringImpl::create8BitIfPossible): ditto.
+ (WTF::StringImpl::lower): 3 of the calls cannot be reached for empty length. On an empty length,
+ the test for (noUpper && !(ored & ~0x7F)) would have caused the function to return "this".
+
+ For the last createUninitialized(), there is no guarantee the realLength is not zero.
+
+ (WTF::StringImpl::replace): The first thing we do in replace(UChar,UChar) is check if there is anything
+ to replace. The check for length will never succeed as there must be a character to replace at that point.
+ * wtf/text/StringImpl.h:
+
2013-08-02 Mark Lam <[email protected]>
Gardening: Touched a line in Platform.h to get all bots to do a clean build.
Modified: trunk/Source/WTF/wtf/text/StringImpl.cpp (153685 => 153686)
--- trunk/Source/WTF/wtf/text/StringImpl.cpp 2013-08-03 03:09:25 UTC (rev 153685)
+++ trunk/Source/WTF/wtf/text/StringImpl.cpp 2013-08-03 03:33:25 UTC (rev 153686)
@@ -191,7 +191,14 @@
data = ""
return empty();
}
+ return createUninitializedInternalNonEmpty(length, data);
+}
+template <typename CharType>
+inline PassRefPtr<StringImpl> StringImpl::createUninitializedInternalNonEmpty(unsigned length, CharType*& data)
+{
+ ASSERT(length);
+
// Allocate a single buffer large enough to contain the StringImpl
// struct as well as the data which it contains. This removes one
// heap allocation from this call.
@@ -255,7 +262,7 @@
return empty();
CharType* data;
- RefPtr<StringImpl> string = createUninitialized(length, data);
+ RefPtr<StringImpl> string = createUninitializedInternalNonEmpty(length, data);
memcpy(data, characters, length * sizeof(CharType));
return string.release();
}
@@ -276,7 +283,7 @@
return empty();
LChar* data;
- RefPtr<StringImpl> string = createUninitialized(length, data);
+ RefPtr<StringImpl> string = createUninitializedInternalNonEmpty(length, data);
for (size_t i = 0; i < length; ++i) {
if (characters[i] & 0xff00)
@@ -393,7 +400,6 @@
// no-op code path up through the first 'return' statement.
// First scan the string for uppercase and non-ASCII characters:
- bool noUpper = true;
if (is8Bit()) {
unsigned failingIndex;
for (unsigned i = 0; i < m_length; ++i) {
@@ -407,7 +413,7 @@
SlowPath8bitLower:
LChar* data8;
- RefPtr<StringImpl> newImpl = createUninitialized(m_length, data8);
+ RefPtr<StringImpl> newImpl = createUninitializedInternalNonEmpty(m_length, data8);
for (unsigned i = 0; i < failingIndex; ++i)
data8[i] = m_data8[i];
@@ -422,6 +428,7 @@
return newImpl.release();
}
+ bool noUpper = true;
unsigned ored = 0;
for (unsigned i = 0; i < m_length; ++i) {
@@ -436,7 +443,7 @@
if (!(ored & ~0x7F)) {
UChar* data16;
- RefPtr<StringImpl> newImpl = createUninitialized(m_length, data16);
+ RefPtr<StringImpl> newImpl = createUninitializedInternalNonEmpty(m_length, data16);
for (unsigned i = 0; i < m_length; ++i) {
UChar c = m_data16[i];
@@ -451,7 +458,7 @@
// Do a slower implementation for cases that include non-ASCII characters.
UChar* data16;
- RefPtr<StringImpl> newImpl = createUninitialized(m_length, data16);
+ RefPtr<StringImpl> newImpl = createUninitializedInternalNonEmpty(m_length, data16);
bool error;
int32_t realLength = Unicode::toLower(data16, length, m_data16, m_length, &error);
@@ -638,7 +645,7 @@
inline PassRefPtr<StringImpl> StringImpl::stripMatchedCharacters(UCharPredicate predicate)
{
if (!m_length)
- return empty();
+ return this;
unsigned start = 0;
unsigned end = m_length - 1;
@@ -1334,7 +1341,7 @@
LChar oldChar = static_cast<LChar>(oldC);
LChar newChar = static_cast<LChar>(newC);
- RefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
+ RefPtr<StringImpl> newImpl = createUninitializedInternalNonEmpty(m_length, data);
for (i = 0; i != m_length; ++i) {
LChar ch = m_data8[i];
@@ -1348,7 +1355,7 @@
// There is the possibility we need to up convert from 8 to 16 bit,
// create a 16 bit string for the result.
UChar* data;
- RefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
+ RefPtr<StringImpl> newImpl = createUninitializedInternalNonEmpty(m_length, data);
for (i = 0; i != m_length; ++i) {
UChar ch = m_data8[i];
@@ -1361,7 +1368,7 @@
}
UChar* data;
- RefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
+ RefPtr<StringImpl> newImpl = createUninitializedInternalNonEmpty(m_length, data);
for (i = 0; i != m_length; ++i) {
UChar ch = m_data16[i];
Modified: trunk/Source/WTF/wtf/text/StringImpl.h (153685 => 153686)
--- trunk/Source/WTF/wtf/text/StringImpl.h 2013-08-03 03:09:25 UTC (rev 153685)
+++ trunk/Source/WTF/wtf/text/StringImpl.h 2013-08-03 03:33:25 UTC (rev 153686)
@@ -807,6 +807,7 @@
template <typename CharType, class UCharPredicate> PassRefPtr<StringImpl> simplifyMatchedCharactersToSpace(UCharPredicate);
template <typename CharType> static PassRefPtr<StringImpl> constructInternal(StringImpl*, unsigned);
template <typename CharType> static PassRefPtr<StringImpl> createUninitializedInternal(unsigned, CharType*&);
+ template <typename CharType> static PassRefPtr<StringImpl> createUninitializedInternalNonEmpty(unsigned, CharType*&);
template <typename CharType> static PassRefPtr<StringImpl> reallocateInternal(PassRefPtr<StringImpl>, unsigned, CharType*&);
template <typename CharType> static PassRefPtr<StringImpl> createInternal(const CharType*, unsigned);
WTF_EXPORT_STRING_API NEVER_INLINE const UChar* getData16SlowCase() const;