Title: [153686] trunk/Source/WTF
Revision
153686
Author
[email protected]
Date
2013-08-02 20:33:25 -0700 (Fri, 02 Aug 2013)

Log Message

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:

Modified Paths

Diff

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;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to