Changeset 1791 in webkit for trunk/JavaScriptCore/kjs


Ignore:
Timestamp:
Aug 9, 2002, 9:31:50 PM (23 years ago)
Author:
darin
Message:

JavaScriptCore:

Some string speedups. Makes sony.com cached 11% faster.

  • kjs/ustring.h: Made it possible for UChar objects to be uninitialized, which gives a speed boost. Inlined CString's +=, UString's destructor, +=, and +.
  • kjs/ustring.cpp: (UString::UString): Optimize const char * version, which showed up heavily in performance analysis. Added new two-UString version, which makes the + operator fast. (UString::ascii): Remove thread safety changes. Change static buffer to remember its size, and to always be at least 4096 bytes long; that way we never have to reallocate unless it's for a long string. Also make code to extract the characters significantly faster by getting rid of two pointer dereferences per character. (UString::is8Bit): Avoid one pointer dereference per character. (UString::toDouble): Use ascii() instead of cstring() to avoid copying the string.
  • kjs/collector.cpp: Remove unneeded APPLE_CHANGES.
  • kjs/regexp.cpp: Remove ifdefs around some APPLE_CHANGES that we want to keep, because they just fix warnings.
  • kjs/value.h: Remove obsolete APPLE_CHANGES comment.
  • JavaScriptCore.pbproj/project.pbxproj: Project Builder decided to move a line around in the file.

WebCore:

  • force-clean-timestamp: JavaScriptCore headers changed that require a full build here.
Location:
trunk/JavaScriptCore/kjs
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/collector.cpp

    r1789 r1791  
    3030#include <typeinfo>
    3131#endif
    32 #ifdef APPLE_CHANGES
    33 #include <pthread.h>
    34 #endif
    3532
    3633namespace KJS {
  • trunk/JavaScriptCore/kjs/regexp.cpp

    r1623 r1791  
    115115    return UString::null; // don't rely on the return value if you pass ovector==0
    116116#else
    117 #ifdef APPLE_CHANGES
    118117  const uint maxMatch = 10;
    119 #else
    120   const int maxMatch = 10;
    121 #endif
    122118  regmatch_t rmatch[maxMatch];
    123119
     
    136132  // map rmatch array to ovector used in PCRE case
    137133  nrSubPatterns = 0;
    138 #ifdef APPLE_CHANGES
    139134  for(uint j = 1; j < maxMatch && rmatch[j].rm_so >= 0 ; j++)
    140 #else
    141   for(int j = 1; j < maxMatch && rmatch[j].rm_so >= 0 ; j++)
    142 #endif
    143135      nrSubPatterns++;
    144136  int ovecsize = (nrSubPatterns+1)*3; // see above
    145137  *ovector = new int[ovecsize];
    146 #ifdef APPLE_CHANGES
    147138  for (uint j = 0; j < nrSubPatterns + 1; j++) {
    148 #else
    149   for (int j = 0; j < nrSubPatterns + 1; j++) {
    150 #endif
    151139    if (j>maxMatch)
    152140      break;
    153141    (*ovector)[2*j] = rmatch[j].rm_so + i;
    154142    (*ovector)[2*j+1] = rmatch[j].rm_eo + i;
    155 #ifdef APPLE_CHANGES
    156   } // balance extra { so we don't confuse prepare-ChangeLog
    157 #else
    158143  }
    159 #endif
    160144#endif
    161145
  • trunk/JavaScriptCore/kjs/ustring.cpp

    r1623 r1791  
    104104}
    105105
    106 CString &CString::operator+=(const CString &str)
    107 {
    108   return append(str.c_str());
    109 }
    110 
    111106int CString::size() const
    112107{
     
    120115
    121116UChar UChar::null;
    122 #ifdef APPLE_CHANGES
    123117UString::Rep UString::Rep::null = { 0, 0, 0, 1 };
    124 #else
    125 UString::Rep UString::Rep::null = { 0, 0, 1 };
    126 #endif
    127118UString UString::null;
    128 #ifdef APPLE_CHANGES
    129 static pthread_once_t statBufferKeyOnce = PTHREAD_ONCE_INIT;
    130 static pthread_key_t statBufferKey;
    131 #else
    132 static char *statBuffer = 0L;
    133 #endif
     119const int normalStatBufferSize = 4096;
     120static char *statBuffer = 0;
     121static int statBufferSize = 0;
    134122
    135123UChar::UChar(const UCharReference &c)
     
    140128UChar UChar::toLower() const
    141129{
    142   // ### properly supprot unicode tolower
     130  // ### properly support unicode tolower
    143131  if (uc >= 256 || islower(uc))
    144132    return *this;
    145133
    146   return UChar(tolower(uc));
     134  return (unsigned char)tolower(uc);
    147135}
    148136
     
    152140    return *this;
    153141
    154   return UChar(toupper(uc));
     142  return (unsigned char)toupper(uc);
    155143}
    156144
     
    177165  r->dat = d;
    178166  r->len = l;
    179 #ifdef APPLE_CHANGES
    180167  r->capacity = l;
    181 #endif
    182168  r->rc = 1;
    183169
     
    194180{
    195181    UChar *d = new UChar[1];
    196     d[0] = UChar(0, c);
     182    d[0] = c;
    197183    rep = Rep::create(d, 1);
    198184}
     
    200186UString::UString(const char *c)
    201187{
    202   attach(&Rep::null);
    203   operator=(c);
     188  if (!c) {
     189    attach(&Rep::null);
     190    return;
     191  }
     192  int length = strlen(c);
     193  UChar *d = new UChar[length];
     194  for (int i = 0; i < length; i++)
     195    d[i].uc = c[i];
     196  rep = Rep::create(d, length);
    204197}
    205198
     
    227220}
    228221
    229 UString::~UString()
    230 {
    231   release();
     222UString::UString(const UString &a, const UString &b)
     223{
     224  int aSize = a.size();
     225  int bSize = b.size();
     226  UChar *d = new UChar[aSize + bSize];
     227  memcpy(d, a.data(), aSize * sizeof(UChar));
     228  memcpy(d + aSize, b.data(), bSize * sizeof(UChar));
     229  rep = Rep::create(d, aSize + bSize);
    232230}
    233231
     
    275273UString &UString::append(const UString &t)
    276274{
    277 #ifdef APPLE_CHANGES
    278275  int l = size();
    279276  int tLen = t.size();
     
    292289  rep = Rep::create(n, newLen);
    293290  rep->capacity = newCapacity;
    294 #else
    295   int l = size();
    296   UChar *n = new UChar[l+t.size()];
    297   memcpy(n, data(), l * sizeof(UChar));
    298   memcpy(n+l, t.data(), t.size() * sizeof(UChar));
    299   release();
    300   rep = Rep::create(n, l + t.size());
    301 #endif
    302291
    303292  return *this;
     
    306295CString UString::cstring() const
    307296{
    308   return CString(ascii());
    309 }
    310 
    311 #ifdef APPLE_CHANGES
    312 static void statBufferKeyCleanup(void *statBuffer)
    313 {
    314   if (statBuffer != NULL)
    315     delete [] (char *)statBuffer;
    316 }
    317 
    318 static void statBufferKeyInit(void)
    319 {
    320   pthread_key_create(&statBufferKey, statBufferKeyCleanup);
    321 }
    322 #endif
     297  return ascii();
     298}
    323299
    324300char *UString::ascii() const
    325301{
    326 #ifdef APPLE_CHANGES
    327   pthread_once(&statBufferKeyOnce, statBufferKeyInit);
    328   char *statBuffer = (char *)pthread_getspecific(statBufferKey);
    329 #endif
    330   if (statBuffer)
     302  // Never make the buffer smaller than normalStatBufferSize.
     303  // Thus we almost never need to reallocate.
     304  int length = size();
     305  int neededSize = length + 1;
     306  if (neededSize < normalStatBufferSize) {
     307    neededSize = normalStatBufferSize;
     308  }
     309  if (neededSize != statBufferSize) {
    331310    delete [] statBuffer;
    332 
    333   statBuffer = new char[size()+1];
    334   for(int i = 0; i < size(); i++)
    335     statBuffer[i] = data()[i].low();
    336   statBuffer[size()] = '\0';
    337 
    338 #ifdef APPLE_CHANGES
    339   pthread_setspecific(statBufferKey, statBuffer);
    340 #endif
     311    statBuffer = new char [neededSize];
     312    statBufferSize = neededSize;
     313  }
     314 
     315  const UChar *p = data();
     316  char *q = statBuffer;
     317  const UChar *limit = p + length;
     318  while (p != limit) {
     319    *q = p->uc;
     320    ++p;
     321    ++q;
     322  }
     323  *q = '\0';
     324
    341325  return statBuffer;
    342326}
     
    346330{
    347331  delete [] statBuffer;
    348   statBuffer = 0L;
     332  statBuffer = 0;
     333  statBufferSize = 0;
    349334}
    350335#endif
     
    352337UString &UString::operator=(const char *c)
    353338{
    354 #ifdef APPLE_CHANGES
    355339  int l = c ? strlen(c) : 0;
    356340  UChar *d;
     
    363347  }
    364348  for (int i = 0; i < l; i++)
    365     d[i].uc = (uchar)c[i];
    366 #else
    367   release();
    368   int l = c ? strlen(c) : 0;
    369 
    370   UChar *d = new UChar[l];
    371   for (int i = 0; i < l; i++)
    372349    d[i].uc = c[i];
    373   rep = Rep::create(d, l);
    374 #endif
    375350
    376351  return *this;
     
    386361}
    387362
    388 UString &UString::operator+=(const UString &s)
    389 {
    390   return append(s);
    391 }
    392 
    393363bool UString::is8Bit() const
    394364{
    395365  const UChar *u = data();
    396   for(int i = 0; i < size(); i++, u++)
     366  const UChar *limit = u + size();
     367  while (u < limit) {
    397368    if (u->uc > 0xFF)
    398369      return false;
     370    ++u;
     371  }
    399372
    400373  return true;
     
    422395    return NaN;
    423396
    424   CString str = cstring();
    425   const char *c = str.c_str();
     397  const char *c = ascii();
    426398
    427399  // skip leading white space
     
    615587  return (l1 < l2);
    616588}
    617 
    618 UString KJS::operator+(const UString& s1, const UString& s2)
    619 {
    620   UString tmp(s1);
    621   tmp.append(s2);
    622 
    623   return tmp;
    624 }
  • trunk/JavaScriptCore/kjs/ustring.h

    r1623 r1791  
    5656   */
    5757  struct UChar {
    58 #ifdef APPLE_CHANGES
    5958    /**
    6059     * Construct a character with uninitialized value.   
    6160     */
    62 #else
    63     /**
    64      * Construct a character with value 0.   
    65      */
    66 #endif
    6761    UChar();
    6862    /**
     
    7670     * @param u 16 bit Unicode value
    7771     */
     72    UChar(char u);
     73    UChar(unsigned char u);
    7874    UChar(unsigned short u);
    7975    UChar(const UCharReference &c);
     
    8581     * @return The lower byte of the character.
    8682     */
    87     unsigned char low() const { return uc & 0xFF; }
     83    unsigned char low() const { return uc; }
    8884    /**
    8985     * @return the 16 bit Unicode value of the character
     
    113109  };
    114110
    115 #ifdef APPLE_CHANGES
    116   inline UChar::UChar() : uc(0) { }
    117 #else
    118111  inline UChar::UChar() { }
    119 #endif
    120112  inline UChar::UChar(unsigned char h , unsigned char l) : uc(h << 8 | l) { }
     113  inline UChar::UChar(char u) : uc((unsigned char)u) { }
     114  inline UChar::UChar(unsigned char u) : uc(u) { }
    121115  inline UChar::UChar(unsigned short u) : uc(u) { }
    122116
     
    190184    CString &operator=(const char *c);
    191185    CString &operator=(const CString &);
    192     CString &operator+=(const CString &);
     186    CString &operator+=(const CString &c) { return append(c); }
    193187
    194188    int size() const;
     
    219213      UChar *dat;
    220214      int len;
    221 #ifdef APPLE_CHANGES
    222215      int capacity;
    223 #endif
    224216      int rc;
    225217      static Rep null;
     
    244236     */
    245237    UString(const UChar *c, int length);
    246 #ifdef APPLE_CHANGES
    247238    /**
    248239     * If copy is false the string data will be adopted.
     
    251242     * Behaviour defaults to a deep copy if copy is true.
    252243     */
    253 #else
    254     /**
    255      * If copy is false a shallow copy of the string will be created. That
    256      * means that the data will NOT be copied and you'll have to guarantee that
    257      * it doesn't get deleted during the lifetime of the UString object.
    258      * Behaviour defaults to a deep copy if copy is true.
    259      */
    260 #endif
    261244    UString(UChar *c, int length, bool copy);
    262245    /**
     
    277260    UString(const DOM::DOMString &);
    278261    /**
     262     * Concatenation constructor. Makes operator+ more efficient.
     263     */
     264    UString(const UString &, const UString &);
     265    /**
    279266     * Destructor. If this handle was the only one holding a reference to the
    280267     * string the data will be freed.
    281268     */
    282     ~UString();
     269    ~UString() { release(); }
    283270
    284271    /**
     
    336323     * Appends the specified string.
    337324     */
    338     UString &operator+=(const UString &s);
     325    UString &operator+=(const UString &s) { return append(s); }
    339326
    340327    /**
     
    435422  }
    436423  bool operator==(const CString& s1, const CString& s2);
    437   UString operator+(const UString& s1, const UString& s2);
     424  inline UString operator+(const UString& s1, const UString& s2) {
     425    return UString(s1, s2);
     426  }
    438427
    439428}; // namespace
  • trunk/JavaScriptCore/kjs/value.h

    r1326 r1791  
    9595    virtual ~ValueImp();
    9696
    97 #ifdef APPLE_CHANGES
    98     // The collector lock is not locked around the ref() and unref()
    99     // methods for the following reasons:
    100     //
    101     // - The only cases where changing the refcount could possibly
    102     // affect the collector's behavior is incrementing from 0 to 1,
    103     // and decrementing from 1 to 0.
    104     //
    105     // - In the 0 to 1 case, the GC allowed flag will always be off
    106     // beforehand, and set right afterwards. And setting it grabs the
    107     // collector lock. So if this happens in the middle of GC, the
    108     // collector will see either a refcount 0 GC not allowed object,
    109     // or a refcount 1 GC not allowed object, and these cases are
    110     // treated exactly the same.
    111     //
    112     // - In the 1 to 0 case, the only possible bad effect is that the
    113     // object will live for one GC cycle longer than it should have
    114     // to, which is really not so bad.
    115     //
    116     // - In theory on some platforms increment or decrement could make
    117     // other threads see intermediate values that are different from
    118     // both the start and end value. If that turns out to really be
    119     // the case we will have to reconsider this scheme.
    120 #endif
    12197    inline ValueImp* ref() { refcount++; return this; }
    12298    inline bool deref() { return (!--refcount); }
Note: See TracChangeset for help on using the changeset viewer.