Changeset 24633 in webkit for trunk/JavaScriptCore/kjs/ustring.cpp
- Timestamp:
- Jul 25, 2007, 2:50:00 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/ustring.cpp
r24394 r24633 27 27 28 28 #include "JSLock.h" 29 #include "collector.h" 29 30 #include "dtoa.h" 30 31 #include "function.h" … … 54 55 extern const double Inf; 55 56 57 // we'd rather not do shared substring append for small strings, since 58 // this runs too much risk of a tiny initial string holding down a 59 // huge buffer. This is also tuned to match the extra cost size, so we 60 // don't ever share a buffer that wouldn't be over the extra cost 61 // threshold already. 62 // FIXME: this should be size_t but that would cause warnings until we 63 // fix UString sizes to be size_t instad of int 64 static const int minShareSize = Collector::minExtraCostSize / sizeof(UChar); 65 56 66 COMPILE_ASSERT(sizeof(UChar) == 2, uchar_is_2_bytes) 57 67 … … 141 151 // Hack here to avoid a global with a constructor; point to an unsigned short instead of a UChar. 142 152 static unsigned short almostUChar; 143 UString::Rep UString::Rep::null = { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 };144 UString::Rep UString::Rep::empty = { 0, 0, 1, 0, 0, 0, reinterpret_cast<UChar*>(&almostUChar), 0, 0, 0, 0 };153 UString::Rep UString::Rep::null = { 0, 0, 1, 0, 0, &UString::Rep::null, 0, 0, 0, 0, 0 }; 154 UString::Rep UString::Rep::empty = { 0, 0, 1, 0, 0, &UString::Rep::empty, reinterpret_cast<UChar*>(&almostUChar), 0, 0, 0, 0 }; 145 155 const int normalStatBufferSize = 4096; 146 156 static char *statBuffer = 0; … … 183 193 ASSERT(JSLock::lockCount() > 0); 184 194 185 Rep *r = new Rep;195 Rep* r = new Rep; 186 196 r->offset = 0; 187 197 r->len = l; … … 189 199 r->_hash = 0; 190 200 r->isIdentifier = 0; 191 r->baseString = 0;201 r->baseString = r; 192 202 r->buf = d; 193 203 r->usedCapacity = l; … … 207 217 int baseOffset = base->offset; 208 218 209 if (base->baseString) { 210 base = base->baseString; 211 } 219 base = base->baseString; 212 220 213 221 assert(-(offset + baseOffset) <= base->usedPreCapacity); … … 237 245 if (isIdentifier) 238 246 Identifier::remove(this); 239 if (baseString ) {247 if (baseString != this) { 240 248 baseString->deref(); 241 249 } else { … … 348 356 inline int UString::usedCapacity() const 349 357 { 350 return m_rep->baseString ? m_rep->baseString->usedCapacity : m_rep->usedCapacity;358 return m_rep->baseString->usedCapacity; 351 359 } 352 360 353 361 inline int UString::usedPreCapacity() const 354 362 { 355 return m_rep->baseString ? m_rep->baseString->usedPreCapacity : m_rep->usedPreCapacity;363 return m_rep->baseString->usedPreCapacity; 356 364 } 357 365 358 366 void UString::expandCapacity(int requiredLength) 359 367 { 360 Rep *r = m_rep->baseString ? m_rep->baseString : rep();368 Rep* r = m_rep->baseString; 361 369 362 370 if (requiredLength > r->capacity) { … … 372 380 void UString::expandPreCapacity(int requiredPreCap) 373 381 { 374 Rep *r = m_rep->baseString ? m_rep->baseString : rep();382 Rep* r = m_rep->baseString; 375 383 376 384 if (requiredPreCap > r->preCapacity) { … … 441 449 // b is empty 442 450 m_rep = a.m_rep; 443 } else if (aOffset + aSize == a.usedCapacity() && 4 * aSize >= bSize &&451 } else if (aOffset + aSize == a.usedCapacity() && aSize >= minShareSize && 4 * aSize >= bSize && 444 452 (-bOffset != b.usedPreCapacity() || aSize >= bSize)) { 445 453 // - a reaches the end of its buffer so it qualifies for shared append … … 454 462 } else 455 463 m_rep = &Rep::null; 456 } else if (-bOffset == b.usedPreCapacity() && 4 * bSize >= aSize) {464 } else if (-bOffset == b.usedPreCapacity() && bSize >= minShareSize && 4 * bSize >= aSize) { 457 465 // - b reaches the beginning of its buffer so it qualifies for shared prepend 458 466 // - also, it's at least a quarter the length of a - prepending to a much shorter … … 680 688 } else if (tSize == 0) { 681 689 // t is empty 682 } else if ( !m_rep->baseString&& m_rep->rc == 1) {690 } else if (m_rep->baseIsSelf() && m_rep->rc == 1) { 683 691 // this is direct and has refcount of 1 (so we can just alter it directly) 684 692 expandCapacity(thisOffset + length); … … 686 694 m_rep->len = length; 687 695 m_rep->_hash = 0; 688 } else if (thisOffset + thisSize == usedCapacity() ) {689 // this reaches the end of the buffer - extend it 696 } else if (thisOffset + thisSize == usedCapacity() && thisSize >= minShareSize) { 697 // this reaches the end of the buffer - extend it if it's long enough to append to 690 698 expandCapacity(thisOffset + length); 691 699 memcpy(const_cast<UChar *>(data() + thisSize), t.data(), tSize * sizeof(UChar)); … … 717 725 } else if (tSize == 0) { 718 726 // t is empty, we'll just return *this below. 719 } else if ( !m_rep->baseString&& m_rep->rc == 1) {727 } else if (m_rep->baseIsSelf() && m_rep->rc == 1) { 720 728 // this is direct and has refcount of 1 (so we can just alter it directly) 721 729 expandCapacity(thisOffset + length); … … 725 733 m_rep->len = length; 726 734 m_rep->_hash = 0; 727 } else if (thisOffset + thisSize == usedCapacity() ) {735 } else if (thisOffset + thisSize == usedCapacity() && thisSize >= minShareSize) { 728 736 // this string reaches the end of the buffer - extend it 729 737 expandCapacity(thisOffset + length); … … 759 767 m_rep = Rep::create(d, 1); 760 768 m_rep->capacity = newCapacity; 761 } else if ( !m_rep->baseString&& m_rep->rc == 1) {769 } else if (m_rep->baseIsSelf() && m_rep->rc == 1) { 762 770 // this is direct and has refcount of 1 (so we can just alter it directly) 763 771 expandCapacity(thisOffset + length + 1); … … 766 774 m_rep->len = length + 1; 767 775 m_rep->_hash = 0; 768 } else if (thisOffset + length == usedCapacity() ) {776 } else if (thisOffset + length == usedCapacity() && length >= minShareSize) { 769 777 // this reaches the end of the string - extend it and share 770 778 expandCapacity(thisOffset + length + 1); … … 831 839 int l = c ? static_cast<int>(strlen(c)) : 0; 832 840 UChar *d; 833 if (m_rep->rc == 1 && l <= m_rep->capacity && !m_rep->baseString&& m_rep->offset == 0 && m_rep->preCapacity == 0) {841 if (m_rep->rc == 1 && l <= m_rep->capacity && m_rep->baseIsSelf() && m_rep->offset == 0 && m_rep->preCapacity == 0) { 834 842 d = m_rep->buf; 835 843 m_rep->_hash = 0; … … 1129 1137 void UString::copyForWriting() 1130 1138 { 1131 if (m_rep->rc > 1 || m_rep->baseString) {1139 if (m_rep->rc > 1 || !m_rep->baseIsSelf()) { 1132 1140 int l = size(); 1133 1141 UChar *n = static_cast<UChar *>(fastMalloc(sizeof(UChar) * l));
Note:
See TracChangeset
for help on using the changeset viewer.