Bug 1156886 - Optimize toLowerCase and toUpperCase on ASCII characters. r=luke
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 22 Apr 2015 11:30:47 +0200
changeset 240416 8d4f212cc9b82bf633c044be633644dce0353343
parent 240415 467559ddc08f63606136089eeba1ec7b191283d6
child 240417 6fe88b38363e572564f8b8e3a878029aa9344df8
push id58826
push userjandemooij@gmail.com
push dateWed, 22 Apr 2015 09:33:49 +0000
treeherdermozilla-inbound@8d4f212cc9b8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1156886
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1156886 - Optimize toLowerCase and toUpperCase on ASCII characters. r=luke
js/src/jsstr.cpp
js/src/vm/Unicode.h
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -598,17 +598,17 @@ ToLowerCase(JSContext* cx, JSLinearStrin
     {
         AutoCheckCannotGC nogc;
         const CharT* chars = str->chars<CharT>(nogc);
 
         // Look for the first upper case character.
         size_t i = 0;
         for (; i < length; i++) {
             char16_t c = chars[i];
-            if (unicode::ToLowerCase(c) != c)
+            if (unicode::CanLowerCase(c))
                 break;
         }
 
         // If all characters are lower case, return the input string.
         if (i == length)
             return str;
 
         newChars = cx->make_pod_array<CharT>(length + 1);
@@ -717,17 +717,17 @@ ToUpperCase(JSContext* cx, JSLinearStrin
     {
         AutoCheckCannotGC nogc;
         const CharT* chars = str->chars<CharT>(nogc);
 
         // Look for the first lower case character.
         size_t i = 0;
         for (; i < length; i++) {
             char16_t c = chars[i];
-            if (unicode::ToUpperCase(c) != c)
+            if (unicode::CanUpperCase(c))
                 break;
         }
 
         // If all characters are upper case, return the input string.
         if (i == length)
             return str;
 
         // If the string is Latin1, check if it contains the MICRO SIGN (0xb5)
--- a/js/src/vm/Unicode.h
+++ b/js/src/vm/Unicode.h
@@ -186,25 +186,55 @@ IsSpaceOrBOM2(char16_t ch)
         return true;
 
     return CharInfo(ch).isSpace();
 }
 
 inline char16_t
 ToUpperCase(char16_t ch)
 {
+    if (ch < 128) {
+        if (ch >= 'a' && ch <= 'z')
+            return ch - ('a' - 'A');
+        return ch;
+    }
+
     const CharacterInfo& info = CharInfo(ch);
 
     return uint16_t(ch) + info.upperCase;
 }
 
 inline char16_t
 ToLowerCase(char16_t ch)
 {
+    if (ch < 128) {
+        if (ch >= 'A' && ch <= 'Z')
+            return ch + ('a' - 'A');
+        return ch;
+    }
+
     const CharacterInfo& info = CharInfo(ch);
 
     return uint16_t(ch) + info.lowerCase;
 }
 
+// Returns true iff ToUpperCase(ch) != ch.
+inline bool
+CanUpperCase(char16_t ch)
+{
+    if (ch < 128)
+        return ch >= 'a' && ch <= 'z';
+    return CharInfo(ch).upperCase != 0;
+}
+
+// Returns true iff ToLowerCase(ch) != ch.
+inline bool
+CanLowerCase(char16_t ch)
+{
+    if (ch < 128)
+        return ch >= 'A' && ch <= 'Z';
+    return CharInfo(ch).lowerCase != 0;
+}
+
 } /* namespace unicode */
 } /* namespace js */
 
 #endif /* vm_Unicode_h */