Title: [106019] trunk/Source/_javascript_Core
Revision
106019
Author
msab...@apple.com
Date
2012-01-26 11:23:50 -0800 (Thu, 26 Jan 2012)

Log Message

Dromaeo tests usage of StringImpl find routines cause 8->16 bit conversions
https://bugs.webkit.org/show_bug.cgi?id=76645

Reviewed by Geoffrey Garen.

* wtf/text/StringImpl.cpp:
(WTF::equalIgnoringCase): New LChar version.
(WTF::findInner): New helper function.
(WTF::StringImpl::find): Added 8 bit path.
(WTF::reverseFindInner): New helper funciton.
(WTF::StringImpl::reverseFind): Added 8 bit path.
(WTF::StringImpl::reverseFindIgnoringCase): Added 8 bit path.
* wtf/text/StringImpl.h:
(WTF):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (106018 => 106019)


--- trunk/Source/_javascript_Core/ChangeLog	2012-01-26 19:23:42 UTC (rev 106018)
+++ trunk/Source/_javascript_Core/ChangeLog	2012-01-26 19:23:50 UTC (rev 106019)
@@ -1,3 +1,20 @@
+2012-01-26  Michael Saboff  <msab...@apple.com>
+
+        Dromaeo tests usage of StringImpl find routines cause 8->16 bit conversions
+        https://bugs.webkit.org/show_bug.cgi?id=76645
+
+        Reviewed by Geoffrey Garen.
+
+        * wtf/text/StringImpl.cpp:
+        (WTF::equalIgnoringCase): New LChar version.
+        (WTF::findInner): New helper function.
+        (WTF::StringImpl::find): Added 8 bit path.
+        (WTF::reverseFindInner): New helper funciton.
+        (WTF::StringImpl::reverseFind): Added 8 bit path.
+        (WTF::StringImpl::reverseFindIgnoringCase): Added 8 bit path.
+        * wtf/text/StringImpl.h:
+        (WTF):
+
 2012-01-26  Csaba Osztrogonác  <o...@webkit.org>
 
         [Qt][Win] One more speculative buildfix after r105970.

Modified: trunk/Source/_javascript_Core/wtf/text/StringImpl.cpp (106018 => 106019)


--- trunk/Source/_javascript_Core/wtf/text/StringImpl.cpp	2012-01-26 19:23:42 UTC (rev 106018)
+++ trunk/Source/_javascript_Core/wtf/text/StringImpl.cpp	2012-01-26 19:23:50 UTC (rev 106019)
@@ -715,6 +715,16 @@
     return charactersToFloat(characters16(), m_length, ok, didReadNumber);
 }
 
+bool equalIgnoringCase(const LChar* a, const LChar* b, unsigned length)
+{
+    while (length--) {
+        LChar bc = *b++;
+        if (foldCase(*a++) != foldCase(bc))
+            return false;
+    }
+    return true;
+}
+
 bool equalIgnoringCase(const UChar* a, const LChar* b, unsigned length)
 {
     while (length--) {
@@ -849,6 +859,35 @@
     return index + i;
 }
 
+template <typename CharType>
+ALWAYS_INLINE static size_t findInner(const CharType* searchCharacters, const CharType* matchCharacters, unsigned index, unsigned searchLength, unsigned matchLength)
+{
+    // Optimization: keep a running hash of the strings,
+    // only call memcmp if the hashes match.
+
+    // delta is the number of additional times to test; delta == 0 means test only once.
+    unsigned delta = searchLength - matchLength;
+
+    unsigned searchHash = 0;
+    unsigned matchHash = 0;
+
+    for (unsigned i = 0; i < matchLength; ++i) {
+        searchHash += searchCharacters[i];
+        matchHash += matchCharacters[i];
+    }
+
+    unsigned i = 0;
+    // keep looping until we match
+    while (searchHash != matchHash || memcmp(searchCharacters + i, matchCharacters, matchLength * sizeof(CharType))) {
+        if (i == delta)
+            return notFound;
+        searchHash += searchCharacters[i + matchLength];
+        searchHash -= searchCharacters[i];
+        ++i;
+    }
+    return index + i;        
+}
+
 size_t StringImpl::find(StringImpl* matchString, unsigned index)
 {
     // Check for null or empty string to match against
@@ -871,31 +910,12 @@
     unsigned searchLength = length() - index;
     if (matchLength > searchLength)
         return notFound;
-    // delta is the number of additional times to test; delta == 0 means test only once.
-    unsigned delta = searchLength - matchLength;
 
-    const UChar* searchCharacters = characters() + index;
-    const UChar* matchCharacters = matchString->characters();
+    if (is8Bit() && matchString->is8Bit())
+        return findInner(characters8() + index, matchString->characters8(), index, searchLength, matchLength);
 
-    // Optimization 2: keep a running hash of the strings,
-    // only call memcmp if the hashes match.
-    unsigned searchHash = 0;
-    unsigned matchHash = 0;
-    for (unsigned i = 0; i < matchLength; ++i) {
-        searchHash += searchCharacters[i];
-        matchHash += matchCharacters[i];
-    }
+    return findInner(characters() + index, matchString->characters(), index, searchLength, matchLength);
 
-    unsigned i = 0;
-    // keep looping until we match
-    while (searchHash != matchHash || memcmp(searchCharacters + i, matchCharacters, matchLength * sizeof(UChar))) {
-        if (i == delta)
-            return notFound;
-        searchHash += searchCharacters[i + matchLength];
-        searchHash -= searchCharacters[i];
-        ++i;
-    }
-    return index + i;
 }
 
 size_t StringImpl::findIgnoringCase(StringImpl* matchString, unsigned index)
@@ -936,33 +956,15 @@
     return WTF::reverseFind(characters16(), m_length, c, index);
 }
 
-size_t StringImpl::reverseFind(StringImpl* matchString, unsigned index)
+template <typename CharType>
+ALWAYS_INLINE static size_t reverseFindInner(const CharType* searchCharacters, const CharType* matchCharacters, unsigned index, unsigned length, unsigned matchLength)
 {
-    // Check for null or empty string to match against
-    if (!matchString)
-        return notFound;
-    unsigned matchLength = matchString->length();
-    if (!matchLength)
-        return min(index, length());
+    // Optimization: keep a running hash of the strings,
+    // only call memcmp if the hashes match.
 
-    // Optimization 1: fast case for strings of length 1.
-    if (matchLength == 1) {
-        if (is8Bit() && matchString->is8Bit())
-            return WTF::reverseFind(characters8(), length(), matchString->characters8()[0], index);
-        return WTF::reverseFind(characters(), length(), matchString->characters()[0], index);
-    }
-
-    // Check index & matchLength are in range.
-    if (matchLength > length())
-        return notFound;
     // delta is the number of additional times to test; delta == 0 means test only once.
-    unsigned delta = min(index, length() - matchLength);
-
-    const UChar *searchCharacters = characters();
-    const UChar *matchCharacters = matchString->characters();
-
-    // Optimization 2: keep a running hash of the strings,
-    // only call memcmp if the hashes match.
+    unsigned delta = min(index, length - matchLength);
+    
     unsigned searchHash = 0;
     unsigned matchHash = 0;
     for (unsigned i = 0; i < matchLength; ++i) {
@@ -971,7 +973,7 @@
     }
 
     // keep looping until we match
-    while (searchHash != matchHash || memcmp(searchCharacters + delta, matchCharacters, matchLength * sizeof(UChar))) {
+    while (searchHash != matchHash || memcmp(searchCharacters + delta, matchCharacters, matchLength * sizeof(CharType))) {
         if (!delta)
             return notFound;
         delta--;
@@ -981,6 +983,33 @@
     return delta;
 }
 
+size_t StringImpl::reverseFind(StringImpl* matchString, unsigned index)
+{
+    // Check for null or empty string to match against
+    if (!matchString)
+        return notFound;
+    unsigned matchLength = matchString->length();
+    unsigned ourLength = length();
+    if (!matchLength)
+        return min(index, ourLength);
+
+    // Optimization 1: fast case for strings of length 1.
+    if (matchLength == 1) {
+        if (is8Bit() && matchString->is8Bit())
+            return WTF::reverseFind(characters8(), ourLength, matchString->characters8()[0], index);
+        return WTF::reverseFind(characters(), ourLength, matchString->characters()[0], index);
+    }
+
+    // Check index & matchLength are in range.
+    if (matchLength > ourLength)
+        return notFound;
+
+    if (is8Bit() && matchString->is8Bit())
+        return reverseFindInner(characters8(), matchString->characters8(), index, ourLength, matchLength);
+
+    return reverseFindInner(characters(), matchString->characters(), index, ourLength, matchLength);
+}
+
 size_t StringImpl::reverseFindIgnoringCase(StringImpl* matchString, unsigned index)
 {
     // Check for null or empty string to match against
@@ -995,7 +1024,20 @@
         return notFound;
     // delta is the number of additional times to test; delta == 0 means test only once.
     unsigned delta = min(index, length() - matchLength);
-    
+
+    if (is8Bit() && matchString->is8Bit()) {
+        const LChar *searchCharacters = characters8();
+        const LChar *matchCharacters = matchString->characters8();
+
+        // keep looping until we match
+        while (!equalIgnoringCase(searchCharacters + delta, matchCharacters, matchLength)) {
+            if (!delta)
+                return notFound;
+            delta--;
+        }
+        return delta;
+    }
+
     const UChar *searchCharacters = characters();
     const UChar *matchCharacters = matchString->characters();
 

Modified: trunk/Source/_javascript_Core/wtf/text/StringImpl.h (106018 => 106019)


--- trunk/Source/_javascript_Core/wtf/text/StringImpl.h	2012-01-26 19:23:42 UTC (rev 106018)
+++ trunk/Source/_javascript_Core/wtf/text/StringImpl.h	2012-01-26 19:23:50 UTC (rev 106019)
@@ -720,6 +720,7 @@
 WTF_EXPORT_PRIVATE bool equalIgnoringCase(StringImpl*, StringImpl*);
 WTF_EXPORT_PRIVATE bool equalIgnoringCase(StringImpl*, const LChar*);
 inline bool equalIgnoringCase(const LChar* a, StringImpl* b) { return equalIgnoringCase(b, a); }
+WTF_EXPORT_PRIVATE bool equalIgnoringCase(const LChar*, const LChar*, unsigned);
 WTF_EXPORT_PRIVATE bool equalIgnoringCase(const UChar*, const LChar*, unsigned);
 inline bool equalIgnoringCase(const UChar* a, const char* b, unsigned length) { return equalIgnoringCase(a, reinterpret_cast<const LChar*>(b), length); }
 inline bool equalIgnoringCase(const LChar* a, const UChar* b, unsigned length) { return equalIgnoringCase(b, a, length); }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to