Reviewed by Dave.
authordarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 8 Feb 2004 21:13:07 +0000 (21:13 +0000)
committerdarin <darin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 8 Feb 2004 21:13:07 +0000 (21:13 +0000)
        - fixed things seen in the profile, for a total speedup of 4% on cvs-base (including changes across all projects)

        * JavaScriptCorePrefix.h: Add a workaround for a bug in our system headers that prevents the <ctype.h>
        macros from working right in C++ code that uses the <cctype> header.

        * kjs/ustring.cpp:
        (KJS::inlineUTF8SequenceLengthNonASCII): Added.
        (KJS::UTF8SequenceLengthNonASCII): Added.
        (KJS::inlineUTF8SequenceLength): Added.
        (KJS::UTF8SequenceLength): Calls inlineUTF8SequenceLengthNonASCII now.
        (KJS::decodeUTF8Sequence): Use new inlineUTF8SequenceLengthNonASCII; faster for ASCII.
        (KJS::createSortedOffsetsArray): Add special case for 1, 2, and 3 offsets, so we don't do qsort for those.
        (KJS::convertUTF16OffsetsToUTF8Offsets): Use new inlineUTF8SequenceLengthNonASCII; faster for ASCII.
        (KJS::convertUTF8OffsetsToUTF16Offsets): Use new inlineUTF8SequenceLengthNonASCII; faster for ASCII.

        - fixed the test program so it won't hit the interpreter lock assertion

        * kjs/testkjs.cpp: (main): Just lock around the whole thing, since the test is singly threaded.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@6051 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCorePrefix.h
JavaScriptCore/kjs/testkjs.cpp
JavaScriptCore/kjs/ustring.cpp

index 7840dc0..5d10013 100644 (file)
@@ -1,3 +1,26 @@
+2004-02-08  Darin Adler  <darin@apple.com>
+
+        Reviewed by Dave.
+
+        - fixed things seen in the profile, for a total speedup of 4% on cvs-base (including changes across all projects)
+
+        * JavaScriptCorePrefix.h: Add a workaround for a bug in our system headers that prevents the <ctype.h>
+        macros from working right in C++ code that uses the <cctype> header.
+
+        * kjs/ustring.cpp:
+        (KJS::inlineUTF8SequenceLengthNonASCII): Added.
+        (KJS::UTF8SequenceLengthNonASCII): Added.
+        (KJS::inlineUTF8SequenceLength): Added.
+        (KJS::UTF8SequenceLength): Calls inlineUTF8SequenceLengthNonASCII now.
+        (KJS::decodeUTF8Sequence): Use new inlineUTF8SequenceLengthNonASCII; faster for ASCII.
+        (KJS::createSortedOffsetsArray): Add special case for 1, 2, and 3 offsets, so we don't do qsort for those.
+        (KJS::convertUTF16OffsetsToUTF8Offsets): Use new inlineUTF8SequenceLengthNonASCII; faster for ASCII.
+        (KJS::convertUTF8OffsetsToUTF16Offsets): Use new inlineUTF8SequenceLengthNonASCII; faster for ASCII.
+
+        - fixed the test program so it won't hit the interpreter lock assertion
+
+        * kjs/testkjs.cpp: (main): Just lock around the whole thing, since the test is singly threaded.
+
 === Safari-127 ===
 
 2004-02-06  Richard Williamson   <rjw@apple.com>
index 6c0e71f..df6f3c1 100644 (file)
 #include <sys/types.h>
 
 #ifdef __cplusplus
+
+// Work around bug 3553309 by re-including <ctype.h>.
+#include <cctype>
+#define isalnum(c)      __istype((c), (_CTYPE_A|_CTYPE_D))
+#define isalpha(c)      __istype((c), _CTYPE_A)
+#define iscntrl(c)      __istype((c), _CTYPE_C)
+#define isdigit(c)      __isctype((c), _CTYPE_D)       /* ANSI -- locale independent */
+#define isgraph(c)      __istype((c), _CTYPE_G)
+#define islower(c)      __istype((c), _CTYPE_L)
+#define isprint(c)      __istype((c), _CTYPE_R)
+#define ispunct(c)      __istype((c), _CTYPE_P)
+#define isspace(c)      __istype((c), _CTYPE_S)
+#define isupper(c)      __istype((c), _CTYPE_U)
+#define isxdigit(c)     __isctype((c), _CTYPE_X)       /* ANSI -- locale independent */
+#define tolower(c)      __tolower(c)
+#define toupper(c)      __toupper(c)
+
 #include <list>
 #include <typeinfo>
+
 #endif
index 856d269..8ce0039 100644 (file)
@@ -72,6 +72,8 @@ int main(int argc, char **argv)
 
   bool ret = true;
   {
+    Interpreter::lock();
+
     Object global(new GlobalImp());
 
     // create interpreter
@@ -127,6 +129,7 @@ int main(int argc, char **argv)
       }
     }
 
+    Interpreter::unlock();
   } // end block, so that Interpreter and global get deleted
 
   if (ret)
index 2cdef0e..74e068e 100644 (file)
@@ -974,13 +974,8 @@ int KJS::compare(const UString& s1, const UString& s2)
   return (l1 < l2) ? 1 : -1;
 }
 
-// Given a first byte, gives the length of the UTF-8 sequence it begins.
-// Returns 0 for bytes that are not legal starts of UTF-8 sequences.
-// Only allows sequences of up to 4 bytes, since that works for all Unicode characters (U-00000000 to U-0010FFFF).
-int UTF8SequenceLength(char b0)
+inline int inlineUTF8SequenceLengthNonASCII(char b0)
 {
-  if ((b0 & 0x80) == 0)
-    return 1;
   if ((b0 & 0xC0) != 0xC0)
     return 0;
   if ((b0 & 0xE0) == 0xC0)
@@ -992,6 +987,24 @@ int UTF8SequenceLength(char b0)
   return 0;
 }
 
+int UTF8SequenceLengthNonASCII(char b0)
+{
+  return inlineUTF8SequenceLengthNonASCII(b0);
+}
+
+inline int inlineUTF8SequenceLength(char b0)
+{
+  return (b0 & 0x80) == 0 ? 1 : UTF8SequenceLengthNonASCII(b0);
+}
+
+// Given a first byte, gives the length of the UTF-8 sequence it begins.
+// Returns 0 for bytes that are not legal starts of UTF-8 sequences.
+// Only allows sequences of up to 4 bytes, since that works for all Unicode characters (U-00000000 to U-0010FFFF).
+int UTF8SequenceLength(char b0)
+{
+  return (b0 & 0x80) == 0 ? 1 : inlineUTF8SequenceLengthNonASCII(b0);
+}
+
 // Takes a null-terminated C-style string with a UTF-8 sequence in it and converts it to a character.
 // Only allows Unicode characters (U-00000000 to U-0010FFFF).
 // Returns -1 if the sequence is not valid (including presence of extra bytes).
@@ -999,7 +1012,7 @@ int decodeUTF8Sequence(const char *sequence)
 {
   // Handle 0-byte sequences (never valid).
   const unsigned char b0 = sequence[0];
-  const int length = UTF8SequenceLength(b0);
+  const int length = inlineUTF8SequenceLength(b0);
   if (length == 0)
     return -1;
 
@@ -1136,15 +1149,71 @@ static StringOffset *createSortedOffsetsArray(const int offsets[], int numOffset
         sortedOffsets = new StringOffset [numOffsets];
     }
 
-    // Copy offsets.
-    for (int i = 0; i != numOffsets; ++i) {
-        sortedOffsets[i].offset = offsets[i];
-        sortedOffsets[i].locationInOffsetsArray = i;
+    // Copy offsets and sort them.
+    // (Since qsort showed up on profiles, hand code for numbers up to 3.)
+
+    switch (numOffsets) {
+        case 0:
+            break;
+        case 1:
+            sortedOffsets[0].offset = offsets[0];
+            sortedOffsets[0].locationInOffsetsArray = 0;
+            break;
+        case 2: {
+            if (offsets[0] <= offsets[1]) {
+                sortedOffsets[0].offset = offsets[0];
+                sortedOffsets[0].locationInOffsetsArray = 0;
+                sortedOffsets[1].offset = offsets[1];
+                sortedOffsets[1].locationInOffsetsArray = 1;
+            } else {
+                sortedOffsets[0].offset = offsets[1];
+                sortedOffsets[0].locationInOffsetsArray = 1;
+                sortedOffsets[1].offset = offsets[0];
+                sortedOffsets[1].locationInOffsetsArray = 0;
+            }
+            break;
+        }
+        case 3: {
+            int i0, i1, i2;
+            if (offsets[0] <= offsets[1]) {
+                if (offsets[0] <= offsets[2]) {
+                    i0 = 0;
+                    if (offsets[1] <= offsets[2]) {
+                        i1 = 1; i2 = 2;
+                    } else {
+                        i1 = 2; i2 = 1;
+                    }
+                } else {
+                    i0 = 2; i1 = 0; i2 = 1;
+                }
+            } else {
+                if (offsets[1] <= offsets[2]) {
+                    i0 = 1;
+                    if (offsets[0] <= offsets[2]) {
+                        i1 = 0; i2 = 2;
+                    } else {
+                        i1 = 2; i2 = 0;
+                    }
+                } else {
+                    i0 = 2; i1 = 1; i2 = 0;
+                }
+            }
+            sortedOffsets[0].offset = offsets[i0];
+            sortedOffsets[0].locationInOffsetsArray = i0;
+            sortedOffsets[1].offset = offsets[i1];
+            sortedOffsets[1].locationInOffsetsArray = i1;
+            sortedOffsets[2].offset = offsets[i2];
+            sortedOffsets[2].locationInOffsetsArray = i2;
+            break;
+        }
+        default:
+            for (int i = 0; i != numOffsets; ++i) {
+                sortedOffsets[i].offset = offsets[i];
+                sortedOffsets[i].locationInOffsetsArray = i;
+            }
+            qsort(sortedOffsets, numOffsets, sizeof(StringOffset), compareStringOffsets);
     }
 
-    // Sort them.
-    qsort(sortedOffsets, numOffsets, sizeof(StringOffset), compareStringOffsets);
-
     return sortedOffsets;
 }
 
@@ -1164,7 +1233,7 @@ void convertUTF16OffsetsToUTF8Offsets(const char *s, int *offsets, int numOffset
         const int nextOffset = sortedOffsets[oi].offset;
         while (*p && UTF16Offset < nextOffset) {
             // Skip to the next character.
-            const int sequenceLength = UTF8SequenceLength(*p);
+            const int sequenceLength = inlineUTF8SequenceLength(*p);
             assert(sequenceLength >= 1 && sequenceLength <= 4);
             p += sequenceLength;
             // Characters that take a 4 byte sequence in UTF-8 take two bytes in UTF-16.
@@ -1195,7 +1264,7 @@ void convertUTF8OffsetsToUTF16Offsets(const char *s, int *offsets, int numOffset
         const int nextOffset = sortedOffsets[oi].offset;
         while (*p && (p - s) < nextOffset) {
             // Skip to the next character.
-            const int sequenceLength = UTF8SequenceLength(*p);
+            const int sequenceLength = inlineUTF8SequenceLength(*p);
             assert(sequenceLength >= 1 && sequenceLength <= 4);
             p += sequenceLength;
             // Characters that take a 4 byte sequence in UTF-8 take two bytes in UTF-16.