Changeset 31677 in webkit for trunk/JavaScriptCore
- Timestamp:
- Apr 6, 2008, 11:33:20 PM (17 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r31577 r31677 1 2008-04-06 Alexey Proskuryakov <[email protected]> 2 3 Reviewed by Darin. 4 5 Make UString thread-safe. 6 7 No change on SunSpider total, although individual tests have changed a lot, up to 3%. 8 9 * kjs/InitializeThreading.cpp: (KJS::initializeThreading): Call UString::null() to initialize 10 a static. 11 12 * kjs/identifier.cpp: 13 (KJS::CStringTranslator::translate): 14 (KJS::UCharBufferTranslator::translate): 15 Use "true" for a boolean value instead of 1, because it's C++. 16 17 * kjs/ustring.h: 18 (KJS::CString::adopt): Added a method to create from a char* buffer without copying. 19 (KJS::UString::Rep::ref): Removed an assertion for JSLock::lockCount, as it's no longer 20 necessary to hold JSLock when working with strings. 21 (KJS::UString::Rep::deref): Ditto. 22 (KJS::UString::Rep::isStatic): Added a field to quickly determine that this is an empty 23 or null static string. 24 25 * kjs/ustring.cpp: 26 (KJS::): Removed normalStatBufferSize and statBufferSize, as there is no reason to have such 27 an advanced implementation of a debug-only ascii() method. Removed a long-obsolete comment 28 about UChar. 29 (KJS::UString::Rep::createCopying): Removed an assertion for JSLock::lockCount. 30 (KJS::UString::Rep::create): Ditto. 31 (KJS::UString::Rep::destroy): Ditto. Do not do anything for static null and empty strings, 32 as refcounting is not reliable for those. Reordered branches for a noticeable speed gain - 33 apparently this functiton is hot enough for SunSpider to see an effect from this! 34 (KJS::UString::null): Moved a star, added a comment. 35 (KJS::UString::cstring): Reimplemented to not call ascii(), which is not thread-safe. 36 (KJS::UString::ascii): Simplified statBuffer handling logic. 37 (KJS::UString::toDouble): Use cstring() instead of ascii(). 38 1 39 2008-04-02 Mark Rowe <[email protected]> 2 40 -
trunk/JavaScriptCore/kjs/InitializeThreading.cpp
r31433 r31677 31 31 32 32 #include "dtoa.h" 33 #include "ustring.h" 33 34 #include <wtf/Threading.h> 34 35 … … 41 42 if (!s_dtoaP5Mutex) 42 43 s_dtoaP5Mutex = new Mutex; 44 UString::null(); 43 45 #endif 44 46 } -
trunk/JavaScriptCore/kjs/identifier.cpp
r31319 r31677 127 127 128 128 UString::Rep *r = UString::Rep::create(d, static_cast<int>(length)).releaseRef(); 129 r->isIdentifier = 1;129 r->isIdentifier = true; 130 130 r->rc = 0; 131 131 r->_hash = hash; … … 184 184 185 185 UString::Rep *r = UString::Rep::create(d, buf.length).releaseRef(); 186 r->isIdentifier = 1;186 r->isIdentifier = true; 187 187 r->rc = 0; 188 188 r->_hash = hash; -
trunk/JavaScriptCore/kjs/ustring.cpp
r30942 r31677 111 111 } 112 112 113 CString CString::adopt(char* c, size_t len) 114 { 115 CString s; 116 s.data = c; 117 s.length = len; 118 119 return s; 120 } 121 113 122 CString &CString::append(const CString &t) 114 123 { … … 163 172 } 164 173 165 // Hack here to avoid a global with a constructor; point to an unsigned short instead of a UChar.174 // These static strings are immutable, except for rc, whose initial value is chosen to reduce the possibility of it becoming zero due to ref/deref not being thread-safe. 166 175 static UChar sharedEmptyChar; 167 UString::Rep UString::Rep::null = { 0, 0, 1, 0, 0, &UString::Rep::null, 0, 0, 0, 0, 0, 0 }; 168 UString::Rep UString::Rep::empty = { 0, 0, 1, 0, 0, &UString::Rep::empty, 0, &sharedEmptyChar, 0, 0, 0, 0 }; 169 const int normalStatBufferSize = 4096; 170 static char *statBuffer = 0; // FIXME: This buffer is never deallocated. 171 static int statBufferSize = 0; 176 UString::Rep UString::Rep::null = { 0, 0, INT_MAX / 2, 0, false, true, &UString::Rep::null, 0, 0, 0, 0, 0, 0 }; 177 UString::Rep UString::Rep::empty = { 0, 0, INT_MAX / 2, 0, false, true, &UString::Rep::empty, 0, &sharedEmptyChar, 0, 0, 0, 0 }; 178 179 static char* statBuffer = 0; // Only used for debugging via UString::ascii(). 172 180 173 181 PassRefPtr<UString::Rep> UString::Rep::createCopying(const UChar *d, int l) 174 182 { 175 ASSERT(JSLock::lockCount() > 0);176 177 183 int sizeInBytes = l * sizeof(UChar); 178 184 UChar *copyD = static_cast<UChar *>(fastMalloc(sizeInBytes)); … … 184 190 PassRefPtr<UString::Rep> UString::Rep::create(UChar *d, int l) 185 191 { 186 ASSERT(JSLock::lockCount() > 0);187 188 192 Rep* r = new Rep; 189 193 r->offset = 0; … … 191 195 r->rc = 1; 192 196 r->_hash = 0; 193 r->isIdentifier = 0; 197 r->isIdentifier = false; 198 r->isStatic = false; 194 199 r->baseString = r; 195 200 r->reportedCost = 0; … … 206 211 PassRefPtr<UString::Rep> UString::Rep::create(PassRefPtr<Rep> base, int offset, int length) 207 212 { 208 ASSERT(JSLock::lockCount() > 0);209 213 ASSERT(base); 210 214 … … 221 225 r->rc = 1; 222 226 r->_hash = 0; 223 r->isIdentifier = 0; 227 r->isIdentifier = false; 228 r->isStatic = false; 224 229 r->baseString = base.releaseRef(); 225 230 r->reportedCost = 0; … … 236 241 void UString::Rep::destroy() 237 242 { 238 ASSERT(JSLock::lockCount() > 0); 239 240 if (isIdentifier) 241 Identifier::remove(this); 242 if (baseString != this) { 243 baseString->deref(); 244 } else { 245 fastFree(buf); 246 } 247 delete this; 243 // Static null and empty strings can never be destroyed, but we cannot rely on reference counting, because ref/deref are not thread-safe. 244 if (!isStatic) { 245 if (isIdentifier) 246 Identifier::remove(this); 247 if (baseString == this) 248 fastFree(buf); 249 else 250 baseString->deref(); 251 252 delete this; 253 } 248 254 } 249 255 … … 519 525 const UString& UString::null() 520 526 { 521 static UString* n = new UString; 527 static UString* n = new UString; // Should be called from main thread at least once to be safely initialized. 522 528 return *n; 523 529 } … … 858 864 CString UString::cstring() const 859 865 { 860 return ascii();861 }862 863 char *UString::ascii() const864 {865 // Never make the buffer smaller than normalStatBufferSize.866 // Thus we almost never need to reallocate.867 866 int length = size(); 868 867 int neededSize = length + 1; 869 if (neededSize < normalStatBufferSize) { 870 neededSize = normalStatBufferSize; 871 } 872 if (neededSize != statBufferSize) { 873 delete [] statBuffer; 874 statBuffer = new char [neededSize]; 875 statBufferSize = neededSize; 876 } 868 char* buf = new char[neededSize]; 869 870 const UChar* p = data(); 871 char* q = buf; 872 const UChar* limit = p + length; 873 while (p != limit) { 874 *q = static_cast<char>(p[0]); 875 ++p; 876 ++q; 877 } 878 *q = '\0'; 879 880 return CString::adopt(buf, length); 881 } 882 883 char *UString::ascii() const 884 { 885 int length = size(); 886 int neededSize = length + 1; 887 delete[] statBuffer; 888 statBuffer = new char[neededSize]; 877 889 878 890 const UChar *p = data(); … … 950 962 return NaN; 951 963 952 const char *c = ascii(); 964 CString s = cstring(); 965 const char* c = s.c_str(); 953 966 954 967 // skip leading white space -
trunk/JavaScriptCore/kjs/ustring.h
r30943 r31677 62 62 ~CString(); 63 63 64 static CString adopt(char* c, size_t len); // c should be allocated with new[]. 65 64 66 CString &append(const CString &); 65 67 CString &operator=(const char *c); … … 102 104 static unsigned computeHash(const char *); 103 105 104 Rep* ref() { ASSERT(JSLock::lockCount() > 0);++rc; return this; }105 ALWAYS_INLINE void deref() { ASSERT(JSLock::lockCount() > 0);if (--rc == 0) destroy(); }106 Rep* ref() { ++rc; return this; } 107 ALWAYS_INLINE void deref() { if (--rc == 0) destroy(); } 106 108 107 109 // unshared data 108 110 int offset; 109 111 int len; 110 int rc; 112 int rc; // For null and empty static strings, this field does not reflect a correct count, because ref/deref are not thread-safe. A special case in destroy() guarantees that these do not get deleted. 111 113 mutable unsigned _hash; 112 bool isIdentifier; 114 bool isIdentifier : 1; 115 bool isStatic : 1; 113 116 UString::Rep* baseString; 114 117 size_t reportedCost; … … 223 226 * Convert the Unicode string to plain ASCII chars chopping of any higher 224 227 * bytes. This method should only be used for *debugging* purposes as it 225 * is neither Unicode safe nor free from side effects . In order not to226 * waste any memory the char buffer is static and *shared* by all UString227 * instances.228 * is neither Unicode safe nor free from side effects nor thread-safe. 229 * In order not to waste any memory the char buffer is static and *shared* 230 * by all UString instances. 228 231 */ 229 232 char* ascii() const;
Note:
See TracChangeset
for help on using the changeset viewer.