source: webkit/trunk/JavaScriptCore/kjs/ustring.h@ 32687

Last change on this file since 32687 was 32609, checked in by Darin Adler, 17 years ago

JavaScriptCore:

2008-04-25 Darin Adler <Darin Adler>

Reviewed by Maciej.

  • fix <rdar://problem/5657459> REGRESSION: JavaScriptCore no longer builds with GCC 4.2 due to pointer aliasing warnings

Fix this by removing the HashTable optimizations that allowed us to share a back end
implementation between hash tables with integers, pointers, RefPtr, and String objects
as keys. The way it worked was incompatible with strict aliasing.

This increases code size. On Mac OS X we'll have to regenerate .order files to avoid
slowing down Safari startup times.

This creates a slight slowdown in SunSpider, mitigated by the following four speedups:

  • speed up array put slightly by moving a branch (was already done for get)
  • speed up symbol table access by adding a function named inlineGet to HashMap and using that in symbolTableGet/Put
  • speed up PropertyNameArray creation by reducing the amount of reference count churn and uniqueness checking when adding names and not doing any allocation at all when building small arrays
  • speed up conversion of strings to floating point numbers by eliminating the malloc/free of the buffer for the ASCII copy of the string; a way to make things even faster would be to change strtod to take a UTF-16 string

Note that there is considerable unused complexity now in HashSet/Map/Table to support
"storage types", which is no longer used. Will do in a separate patch.

  • API/JSCallbackObjectFunctions.h: (KJS::JSCallbackObject<Base>::getPropertyNames): Removed explicit cast to Identifier to take advantage of the new PropertyNameArray::add overload and avoid reference count churn.
  • API/JSObjectRef.cpp: (JSPropertyNameAccumulatorAddName): Ditto.
  • JavaScriptCore.exp: Updated PropertyNameArray::add entry point name.
  • kjs/JSVariableObject.cpp: Removed now-unneeded IdentifierRepHashTraits::nullRepPtr definition (see below). (KJS::JSVariableObject::getPropertyNames): Removed explicit cast to Identifier.
  • kjs/JSVariableObject.h: (KJS::JSVariableObject::symbolTableGet): Use inlineGet for speed. Also changed to do early exit instead of nesting the body inside an if. (KJS::JSVariableObject::symbolTablePut): Ditto.
  • kjs/PropertyNameArray.cpp: (KJS::PropertyNameArray::add): Changed implementation to take a raw pointer instead of a reference to an identifier. Do uniqueness checking by searching the vector when the vector is short, only building the set once the vector is large enough.
  • kjs/PropertyNameArray.h: Added an overload of add for a raw pointer, and made the old add function call that one. Added an addKnownUnique function for use when the new name is known to be different from any other in the array. Changed the vector to have an inline capacity of 20.
  • kjs/SymbolTable.h: Changed IdentifierRepHash to inherit from the default hash for a RefPtr so we don't have to define so much. Added an overload of the hash function for a raw pointer as required by the new RefPtrHashMap. Got rid of the now-unneeded IdentifierRepHashTraits -- the default traits now work fine. Added a definition of empthValueIsZero to SymbolTableIndexHashTraits; not having it was incorrect, but harmless.
  • kjs/array_instance.cpp: (KJS::ArrayInstance::put): Move the maxArrayIndex check inside the branch that checks the index against the length, as done in the get function.
  • kjs/function.cpp: (KJS::globalFuncKJSPrint): Changed to use the new getCString instead of cstring.
  • kjs/internal.cpp: Removed printInfo debugging function, a client of cstring. If we need a debugging function we can easily make a better one and we haven't used this one in a long time.
  • kjs/internal.h: Ditto.
  • kjs/object.cpp: (KJS::JSObject::getPropertyNames): Removed explicit cast to Identifier.
  • kjs/property_map.cpp: (KJS::PropertyMap::getEnumerablePropertyNames): Ditto. Also added a special case for the case where the propertyNames array is empty -- in that case we know we're adding a set of names that are non-overlapping so we can use addKnownUnique.
  • kjs/ustring.cpp: (KJS::UString::getCString): Replaces cstring. Puts the C string into a CStringBuffer, which is a char Vector with an inline capacity. Also returns a boolean to indicate if the converion was lossy, which eliminates the need for a separate is8Bit call. (KJS::UString::toDouble): Changed to call getCString instead of cstring.
  • kjs/ustring.h: Ditto.
  • wtf/HashFunctions.h: Overload the hash and equal functions for RefPtr's default hash to take raw pointers. This works with the changes to RefPtrHashMap to avoid introducing refcount churn.
  • wtf/HashMap.h: Removed special code to convert the deleted value to the empty value when writing a new value into the map. This is now handled elsewhere. (WTF::HashMap::get): Removed code that checks for an empty hash table before calling HashTable::lookup; it's slightly more efficient to do this check inside lookup.
  • wtf/HashTable.h: (WTF::HashTable::isDeletedBucket): Changed to use isDeletedValue instead of using deletedValue and the equality operator. (WTF::HashTable::deleteBucket): Changed to use constructDeletedValue instead of using deletedValue and the assignment operator. (WTF::HashTable::checkKey): Added. Factors out the check for values that are empty or deleted keys that's used in various functions below. (WTF::HashTable::lookup): Changed to use checkKey, check for a 0 table, and also made public for use by RefPtrHashMap. (WTF::HashTable::lookupForWriting): Changed to use checkKey. (WTF::HashTable::fullLookupForWriting): Changed to use checkKey. (WTF::HashTable::add): Changed to use checkKey, and call initializeBucket on a deleted bucket before putting a new entry into it. (WTF::HashTable::addPassingHashCode): Ditto. (WTF::HashTable::deallocateTable): Check isDeletedBucket before calling ~ValueType.
  • wtf/HashTraits.h: Got ridd of all the HashTraits specialization for the integer types, since GeneicHashTraitsBase already deals with integers separately. Put the deleted value support into GenericHashTraitsBase. Changed FloatHashTraits to inherit from GenericHashTraits, and define construct/isDeletedValue rather than deletedValue. Removed the ref and deref functions from RefPtr's HashTraits, and defined construct/isDeletedValue. Eliminated DeletedValueAssigner. Changed PairHashTraits to define construct/isDeletedValue, and also merged PairBaseHashTraits in with PairHashTraits. Got rid of all specialization of HashKeyStorageTraits. We'll remove that, and the needsRef data member, later.
  • wtf/RefPtr.h: Added HashTableDeletedValueType, an enum type with a single value, HashTableDeletedValue. Used that type to make a new constructor to construct deleted values and also added an isHashTableDeletedValue function.
  • wtf/RefPtrHashMap.h: Added RefPtrHashMapRawKeyTranslator and used it to implement the raw pointer functions. This is a way to continue to avoid refcount thrash. We can't use the old way because it depended on the underlying map using a non-RefPtr type. (WTF::HashMap::find): Use find with RefPtrHashMapRawKeyTranslator. (WTF::HashMap::contains): Use contains with RefPtrHashMapRawKeyTranslator. (WTF::HashMap::inlineAdd): Use add with RefPtrHashMapRawKeyTranslator. (WTF::HashMap::get): Removed code that checks for an empty hash table before calling HashTable::lookup; it's slightly more efficient to do this check inside lookup. (WTF::HashMap::inlineGet): Added. Just like get, but marked inline for use in the symbol table code.

WebCore:

2008-04-25 Darin Adler <Darin Adler>

Reviewed by Maciej.

  • update for compatibility with HashTable that no longer has optimization to share implementation between hash tables with integers, pointers, RefPtr, and String objects as keys
  • bindings/js/JSSVGPODTypeWrapper.h: (WebCore::PODTypeReadWriteHashInfo::PODTypeReadWriteHashInfo): Added constructor for HashTableDeletedValue. (WebCore::PODTypeReadWriteHashInfo::isHashTableDeletedValue): Added. (WebCore::PODTypeReadWriteHashInfoTraits::constructDeletedValue): Added. (WebCore::PODTypeReadWriteHashInfoTraits::isDeletedValue): Added.
  • dom/Document.cpp: Made changedDocuments internal to the file rather than a static data member of Document. (WebCore::FormElementKey::ref): Removed unneeded check for deleted value -- this will never be called on a deleted element. (WebCore::FormElementKey::deref): Ditto.
  • dom/Document.h: Added HashTableDeletedValue constructor and isHashTableDeletedValue to FormElementKey. Changed FormElementKeyHashTraits to use construct/isDeletedValue. Got rid of the changedDocuments data member. Changed iconURL to be an inline that returns a const String&.
  • dom/StyledElement.cpp: Changed MappedAttributeKeyTraits to use construct/isDeletedValue.
  • page/mac/AXObjectCacheMac.mm: (WebCore::AXObjectCache::getAXID): Call isDeletedValue instead of deletedValue.
  • platform/SecurityOriginHash.h: Added overload so that SecurityOriginHash can work with raw pointers as well as RefPt (helpful with the new RefPtrHashMap). Eliminated SecurityOriginTraits, since we can now use the default traits. Changed the value of safeToCompareToEmptyOrDeleted to false, since it's not safe to compare a deleted value using this hash function. I don't think it was safe before either; I'm not sure why it didn't cause a problem before.
  • platform/cf/SchedulePair.h: Removed SchedulePairTraits -- custom traits are no longer needed.
  • platform/graphics/FontCache.cpp: (WebCore::FontPlatformDataCacheKey::FontPlatformDataCacheKey): Added constructor for HashTableDeletedValue. (WebCore::FontPlatformDataCacheKey::isHashTableDeletedValue): Added. (WebCore::FontPlatformDataCacheKey::hashTableDeletedSize): Added. (WebCore::FontPlatformDataCacheKeyTraits::constructDeletedValue): Added. (WebCore::FontPlatformDataCacheKeyTraits::isDeletedValue): Added. (WebCore::FontDataCacheKeyTraits::constructDeletedValue): Added. (WebCore::FontDataCacheKeyTraits::isDeletedValue): Added.
  • platform/graphics/IntSizeHash.h: Changed HashTraits<IntSize> to use construct/isDeletedValue.
  • platform/graphics/mac/FontPlatformData.h: (WebCore::FontPlatformData::FontPlatformData): Added constructor for HashTableDeletedValue. (WebCore::FontPlatformData::isHashTableDeletedValue): Added. (WebCore::FontPlatformData::hashTableDeletedFontValue): Added.
  • platform/text/PlatformString.h: (WebCore::String::swap): Added. Avoids any refcount churn when swapping two strings. (WebCore::String::String): Added constructor for HashTableDeletedValue. (WebCore::String::isHashTableDeletedValue): Added. (WebCore::swap): Added. Avoids any refcount churn when swapping two strings.
  • platform/text/StringHash.h: Changed specialization of HashTraits for WebCore::String to use the deleted value now defined in that class and removed the code to do ref/deref. Removed HashKeyStorageTraits specializations.


  • platform/win/COMPtr.h: Changed specialization of HashTraits for COMPtr to use the deleted value now defined in that class and removed the code to do ref/deref. Removed HashKeyStorageTraits specializations. (COMPtr::COMPtr): Added constructor for HashTableDeletedValue. (COMPtr::isHashTableDeletedValue): Added. (COMPtr::query): Removed inline keyword not needed since functions defined in the class definition are automatically marked inline. (COMPtr::hashTableDeletedValue): Added.
  • storage/DatabaseTracker.h: Removed now-unneeded SecurityOriginTraits.
  • storage/LocalStorage.h: Ditto.
  • storage/OriginQuotaManager.h: Ditto.
  • storage/SessionStorage.h: Ditto.
  • svg/SVGAnimatedTemplate.h: (WebCore::SVGAnimatedTypeWrapperKey::SVGAnimatedTypeWrapperKey): Added constructor for HashTableDeletedValue. (WebCore::SVGAnimatedTypeWrapperKey::isHashTableDeletedValue): Added. (WebCore::SVGAnimatedTypeWrapperKeyHashTraits::constructDeletedValue): Added. (WebCore::SVGAnimatedTypeWrapperKeyHashTraits::isDeletedValue): Added.
  • Property svn:eol-style set to native
File size: 13.0 KB
Line 
1// -*- c-basic-offset: 2 -*-
2/*
3 * Copyright (C) 1999-2000 Harri Porten ([email protected])
4 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#ifndef _KJS_USTRING_H_
24#define _KJS_USTRING_H_
25
26#include "JSLock.h"
27#include "collector.h"
28#include <stdint.h>
29#include <wtf/Assertions.h>
30#include <wtf/FastMalloc.h>
31#include <wtf/PassRefPtr.h>
32#include <wtf/RefPtr.h>
33#include <wtf/unicode/Unicode.h>
34#include <wtf/Vector.h>
35
36/**
37 * @internal
38 */
39namespace DOM {
40 class DOMString;
41 class AtomicString;
42}
43class KJScript;
44
45namespace KJS {
46
47 using WTF::PlacementNewAdoptType;
48 using WTF::PlacementNewAdopt;
49
50 class IdentifierTable;
51 class UString;
52
53 /**
54 * @short 8 bit char based string class
55 */
56 class CString {
57 public:
58 CString() : data(0), length(0) { }
59 CString(const char *c);
60 CString(const char *c, size_t len);
61 CString(const CString &);
62
63 ~CString();
64
65 static CString adopt(char* c, size_t len); // c should be allocated with new[].
66
67 CString &append(const CString &);
68 CString &operator=(const char *c);
69 CString &operator=(const CString &);
70 CString &operator+=(const CString &c) { return append(c); }
71
72 size_t size() const { return length; }
73 const char *c_str() const { return data; }
74 private:
75 char *data;
76 size_t length;
77 };
78
79 typedef Vector<char, 32> CStringBuffer;
80
81 /**
82 * @short Unicode string class
83 */
84 class UString {
85 friend bool operator==(const UString&, const UString&);
86
87 public:
88 /**
89 * @internal
90 */
91 struct Rep {
92
93 static PassRefPtr<Rep> create(UChar *d, int l);
94 static PassRefPtr<Rep> createCopying(const UChar *d, int l);
95 static PassRefPtr<Rep> create(PassRefPtr<Rep> base, int offset, int length);
96
97 void destroy();
98
99 bool baseIsSelf() const { return baseString == this; }
100 UChar* data() const { return baseString->buf + baseString->preCapacity + offset; }
101 int size() const { return len; }
102
103 unsigned hash() const { if (_hash == 0) _hash = computeHash(data(), len); return _hash; }
104 unsigned computedHash() const { ASSERT(_hash); return _hash; } // fast path for Identifiers
105
106 static unsigned computeHash(const UChar *, int length);
107 static unsigned computeHash(const char *);
108
109 Rep* ref() { ++rc; return this; }
110 ALWAYS_INLINE void deref() { if (--rc == 0) destroy(); }
111
112 // unshared data
113 int offset;
114 int len;
115 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.
116 mutable unsigned _hash;
117 IdentifierTable* identifierTable; // 0 if not an identifier. Since garbage collection can happen on a different thread, there is no other way to get to the table during destruction.
118 UString::Rep* baseString;
119 bool isStatic : 1;
120 size_t reportedCost : 31;
121
122 // potentially shared data
123 UChar *buf;
124 int usedCapacity;
125 int capacity;
126 int usedPreCapacity;
127 int preCapacity;
128
129 static Rep null;
130 static Rep empty;
131 };
132
133 public:
134
135 /**
136 * Constructs a null string.
137 */
138 UString();
139 /**
140 * Constructs a string from a classical zero-terminated char string.
141 */
142 UString(const char *c);
143 /**
144 * Constructs a string from an array of Unicode characters of the specified
145 * length.
146 */
147 UString(const UChar *c, int length);
148 /**
149 * If copy is false the string data will be adopted.
150 * That means that the data will NOT be copied and the pointer will
151 * be deleted when the UString object is modified or destroyed.
152 * Behaviour defaults to a deep copy if copy is true.
153 */
154 UString(UChar *c, int length, bool copy);
155 /**
156 * Copy constructor. Makes a shallow copy only.
157 */
158 UString(const UString &s) : m_rep(s.m_rep) {}
159
160 UString(const Vector<UChar>& buffer);
161
162 /**
163 * Convenience declaration only ! You'll be on your own to write the
164 * implementation for a construction from DOM::DOMString.
165 *
166 * Note: feel free to contact me if you want to see a dummy header for
167 * your favorite FooString class here !
168 */
169 UString(const DOM::DOMString&);
170 /**
171 * Convenience declaration only ! See UString(const DOM::DOMString&).
172 */
173 UString(const DOM::AtomicString&);
174
175 /**
176 * Concatenation constructor. Makes operator+ more efficient.
177 */
178 UString(const UString &, const UString &);
179 /**
180 * Destructor.
181 */
182 ~UString() {}
183
184 // Special constructor for cases where we overwrite an object in place.
185 UString(PlacementNewAdoptType) : m_rep(PlacementNewAdopt) { }
186
187 /**
188 * Constructs a string from an int.
189 */
190 static UString from(int i);
191 /**
192 * Constructs a string from an unsigned int.
193 */
194 static UString from(unsigned int u);
195 /**
196 * Constructs a string from a long int.
197 */
198 static UString from(long u);
199 /**
200 * Constructs a string from a double.
201 */
202 static UString from(double d);
203
204 struct Range {
205 public:
206 Range(int pos, int len) : position(pos), length(len) {}
207 Range() {}
208 int position;
209 int length;
210 };
211
212 UString spliceSubstringsWithSeparators(const Range* substringRanges, int rangeCount, const UString* separators, int separatorCount) const;
213
214 /**
215 * Append another string.
216 */
217 UString& append(const UString&);
218 UString& append(const char*);
219 UString& append(UChar);
220 UString& append(char c) { return append(static_cast<UChar>(static_cast<unsigned char>(c))); }
221
222 /**
223 * @return The string converted to the 8-bit string type CString().
224 * Returns false if any character is non-ASCII.
225 */
226 bool getCString(CStringBuffer&) const;
227
228 /**
229 * Convert the Unicode string to plain ASCII chars chopping off any higher
230 * bytes. This method should only be used for *debugging* purposes as it
231 * is neither Unicode safe nor free from side effects nor thread-safe.
232 * In order not to waste any memory the char buffer is static and *shared*
233 * by all UString instances.
234 */
235 char* ascii() const;
236
237 /**
238 * Convert the string to UTF-8, assuming it is UTF-16 encoded.
239 * In non-strict mode, this function is tolerant of badly formed UTF-16, it
240 * can create UTF-8 strings that are invalid because they have characters in
241 * the range U+D800-U+DDFF, U+FFFE, or U+FFFF, but the UTF-8 string is
242 * guaranteed to be otherwise valid.
243 * In strict mode, error is returned as null CString.
244 */
245 CString UTF8String(bool strict = false) const;
246
247 /**
248 * @see UString(const DOM::DOMString&).
249 */
250 DOM::DOMString domString() const;
251
252 /**
253 * Assignment operator.
254 */
255 UString &operator=(const char *c);
256 /**
257 * Appends the specified string.
258 */
259 UString &operator+=(const UString &s) { return append(s); }
260 UString &operator+=(const char *s) { return append(s); }
261
262 /**
263 * @return A pointer to the internal Unicode data.
264 */
265 const UChar* data() const { return m_rep->data(); }
266 /**
267 * @return True if null.
268 */
269 bool isNull() const { return (m_rep == &Rep::null); }
270 /**
271 * @return True if null or zero length.
272 */
273 bool isEmpty() const { return (!m_rep->len); }
274 /**
275 * Use this if you want to make sure that this string is a plain ASCII
276 * string. For example, if you don't want to lose any information when
277 * using cstring() or ascii().
278 *
279 * @return True if the string doesn't contain any non-ASCII characters.
280 */
281 bool is8Bit() const;
282 /**
283 * @return The length of the string.
284 */
285 int size() const { return m_rep->size(); }
286 /**
287 * Const character at specified position.
288 */
289 UChar operator[](int pos) const;
290
291 /**
292 * Attempts an conversion to a number. Apart from floating point numbers,
293 * the algorithm will recognize hexadecimal representations (as
294 * indicated by a 0x or 0X prefix) and +/- Infinity.
295 * Returns NaN if the conversion failed.
296 * @param tolerateTrailingJunk if true, toDouble can tolerate garbage after the number.
297 * @param tolerateEmptyString if false, toDouble will turn an empty string into NaN rather than 0.
298 */
299 double toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const;
300 double toDouble(bool tolerateTrailingJunk) const;
301 double toDouble() const;
302
303 /**
304 * Attempts an conversion to a 32-bit integer. ok will be set
305 * according to the success.
306 * @param tolerateEmptyString if false, toUInt32 will return false for *ok for an empty string.
307 */
308 uint32_t toUInt32(bool *ok = 0) const;
309 uint32_t toUInt32(bool *ok, bool tolerateEmptyString) const;
310 uint32_t toStrictUInt32(bool *ok = 0) const;
311
312 /**
313 * Attempts an conversion to an array index. The "ok" boolean will be set
314 * to true if it is a valid array index according to the rule from
315 * ECMA 15.2 about what an array index is. It must exactly match the string
316 * form of an unsigned integer, and be less than 2^32 - 1.
317 */
318 unsigned toArrayIndex(bool *ok = 0) const;
319
320 /**
321 * @return Position of first occurrence of f starting at position pos.
322 * -1 if the search was not successful.
323 */
324 int find(const UString &f, int pos = 0) const;
325 int find(UChar, int pos = 0) const;
326 /**
327 * @return Position of first occurrence of f searching backwards from
328 * position pos.
329 * -1 if the search was not successful.
330 */
331 int rfind(const UString &f, int pos) const;
332 int rfind(UChar, int pos) const;
333 /**
334 * @return The sub string starting at position pos and length len.
335 */
336 UString substr(int pos = 0, int len = -1) const;
337 /**
338 * Static instance of a null string.
339 */
340 static const UString &null();
341
342 Rep* rep() const { return m_rep.get(); }
343 UString(PassRefPtr<Rep> r) : m_rep(r) { ASSERT(m_rep); }
344
345 size_t cost() const;
346
347 private:
348 size_t expandedSize(size_t size, size_t otherSize) const;
349 int usedCapacity() const;
350 int usedPreCapacity() const;
351 void expandCapacity(int requiredLength);
352 void expandPreCapacity(int requiredPreCap);
353
354 RefPtr<Rep> m_rep;
355 };
356
357 bool operator==(const UString& s1, const UString& s2);
358 inline bool operator!=(const UString& s1, const UString& s2) {
359 return !KJS::operator==(s1, s2);
360 }
361 bool operator<(const UString& s1, const UString& s2);
362 bool operator==(const UString& s1, const char *s2);
363 inline bool operator!=(const UString& s1, const char *s2) {
364 return !KJS::operator==(s1, s2);
365 }
366 inline bool operator==(const char *s1, const UString& s2) {
367 return operator==(s2, s1);
368 }
369 inline bool operator!=(const char *s1, const UString& s2) {
370 return !KJS::operator==(s1, s2);
371 }
372 bool operator==(const CString& s1, const CString& s2);
373 inline UString operator+(const UString& s1, const UString& s2) {
374 return UString(s1, s2);
375 }
376
377 int compare(const UString &, const UString &);
378
379inline UString::UString()
380 : m_rep(&Rep::null)
381{
382}
383
384// Rule from ECMA 15.2 about what an array index is.
385// Must exactly match string form of an unsigned integer, and be less than 2^32 - 1.
386inline unsigned UString::toArrayIndex(bool *ok) const
387{
388 unsigned i = toStrictUInt32(ok);
389 if (ok && i >= 0xFFFFFFFFU)
390 *ok = false;
391 return i;
392}
393
394// We'd rather not do shared substring append for small strings, since
395// this runs too much risk of a tiny initial string holding down a
396// huge buffer.
397// FIXME: this should be size_t but that would cause warnings until we
398// fix UString sizes to be size_t instead of int
399static const int minShareSize = Collector::minExtraCostSize / sizeof(UChar);
400
401inline size_t UString::cost() const
402{
403 size_t capacity = (m_rep->baseString->capacity + m_rep->baseString->preCapacity) * sizeof(UChar);
404 size_t reportedCost = m_rep->baseString->reportedCost;
405 ASSERT(capacity >= reportedCost);
406
407 size_t capacityDelta = capacity - reportedCost;
408
409 if (capacityDelta < static_cast<size_t>(minShareSize))
410 return 0;
411
412#if COMPILER(MSVC)
413// MSVC complains about this assignment, since reportedCost is a 31-bit size_t.
414#pragma warning(push)
415#pragma warning(disable: 4267)
416#endif
417
418 m_rep->baseString->reportedCost = capacity;
419
420#if COMPILER(MSVC)
421#pragma warning(pop)
422#endif
423
424 return capacityDelta;
425}
426
427} // namespace
428
429#endif
Note: See TracBrowser for help on using the repository browser.