Changeset 58001 in webkit for trunk/JavaScriptCore/runtime/UStringImpl.h
- Timestamp:
- Apr 21, 2010, 12:13:50 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/UStringImpl.h
r57932 r58001 1 1 /* 2 * Copyright (C) 2009 Apple Inc. All rights reserved. 2 * Copyright (C) 1999 Lars Knoll ([email protected]) 3 * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. 4 * Copyright (C) 2009 Google Inc. All rights reserved. 3 5 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 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. 12 10 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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 * 24 21 */ 25 22 … … 27 24 #define UStringImpl_h 28 25 29 #include <limits> 30 #include <wtf/CrossThreadRefCounted.h> 31 #include <wtf/OwnFastMallocPtr.h> 32 #include <wtf/PossiblyNull.h> 33 #include <wtf/StringHashFunctions.h> 34 #include <wtf/Vector.h> 35 #include <wtf/unicode/Unicode.h> 36 #include <wtf/text/StringImplBase.h> 37 38 namespace JSC { 39 40 class IdentifierTable; 41 42 typedef OwnFastMallocPtr<const UChar> SharableUChar; 43 typedef CrossThreadRefCounted<SharableUChar> SharedUChar; 44 45 class UStringImpl : public StringImplBase { 46 friend struct CStringTranslator; 47 friend struct UCharBufferTranslator; 48 friend class JIT; 49 friend class SmallStringsStorage; 50 friend void initializeUString(); 51 private: 52 // For SmallStringStorage, which allocates an array and uses an in-place new. 53 UStringImpl() { } 54 55 // Used to construct static strings, which have an special refCount that can never hit zero. 56 // This means that the static string will never be destroyed, which is important because 57 // static strings will be shared across threads & ref-counted in a non-threadsafe manner. 58 UStringImpl(const UChar* characters, unsigned length, StaticStringConstructType) 59 : StringImplBase(length, ConstructStaticString) 60 , m_data(characters) 61 , m_buffer(0) 62 , m_hash(0) 63 { 64 hash(); 65 } 66 67 // Create a normal string with internal storage (BufferInternal) 68 UStringImpl(unsigned length) 69 : StringImplBase(length, BufferInternal) 70 , m_data(reinterpret_cast<UChar*>(this + 1)) 71 , m_buffer(0) 72 , m_hash(0) 73 { 74 ASSERT(m_data); 75 ASSERT(m_length); 76 } 77 78 // Create a UStringImpl adopting ownership of the provided buffer (BufferOwned) 79 UStringImpl(const UChar* characters, unsigned length) 80 : StringImplBase(length, BufferOwned) 81 , m_data(characters) 82 , m_buffer(0) 83 , m_hash(0) 84 { 85 ASSERT(m_data); 86 ASSERT(m_length); 87 } 88 89 // Used to create new strings that are a substring of an existing UStringImpl (BufferSubstring) 90 UStringImpl(const UChar* characters, unsigned length, PassRefPtr<UStringImpl> base) 91 : StringImplBase(length, BufferSubstring) 92 , m_data(characters) 93 , m_substringBuffer(base.releaseRef()) 94 , m_hash(0) 95 { 96 ASSERT(m_data); 97 ASSERT(m_length); 98 ASSERT(m_substringBuffer->bufferOwnership() != BufferSubstring); 99 } 100 101 // Used to construct new strings sharing an existing SharedUChar (BufferShared) 102 UStringImpl(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer) 103 : StringImplBase(length, BufferShared) 104 , m_data(characters) 105 , m_sharedBuffer(sharedBuffer.releaseRef()) 106 , m_hash(0) 107 { 108 ASSERT(m_data); 109 ASSERT(m_length); 110 } 111 112 // For use only by Identifier's XXXTranslator helpers. 113 void setHash(unsigned hash) 114 { 115 ASSERT(!isStatic()); 116 ASSERT(!m_hash); 117 ASSERT(hash == computeHash(m_data, m_length)); 118 m_hash = hash; 119 } 120 121 public: 122 ~UStringImpl(); 123 124 static PassRefPtr<UStringImpl> create(const UChar*, unsigned length); 125 static PassRefPtr<UStringImpl> create(const char*, unsigned length); 126 static PassRefPtr<UStringImpl> create(const char*); 127 static PassRefPtr<UStringImpl> create(const UChar*, unsigned length, PassRefPtr<SharedUChar>); 128 static PassRefPtr<UStringImpl> create(PassRefPtr<UStringImpl> rep, unsigned offset, unsigned length) 129 { 130 ASSERT(rep); 131 ASSERT(length <= rep->length()); 132 133 if (!length) 134 return empty(); 135 136 UStringImpl* ownerRep = (rep->bufferOwnership() == BufferSubstring) ? rep->m_substringBuffer : rep.get(); 137 return adoptRef(new UStringImpl(rep->m_data + offset, length, ownerRep)); 138 } 139 140 static PassRefPtr<UStringImpl> createUninitialized(unsigned length, UChar*& output); 141 static PassRefPtr<UStringImpl> tryCreateUninitialized(unsigned length, UChar*& output) 142 { 143 if (!length) { 144 output = 0; 145 return empty(); 146 } 147 148 if (length > ((std::numeric_limits<size_t>::max() - sizeof(UStringImpl)) / sizeof(UChar))) 149 return 0; 150 UStringImpl* resultImpl; 151 if (!tryFastMalloc(sizeof(UChar) * length + sizeof(UStringImpl)).getValue(resultImpl)) 152 return 0; 153 output = reinterpret_cast<UChar*>(resultImpl + 1); 154 return adoptRef(new(resultImpl) UStringImpl(length)); 155 } 156 157 template<size_t inlineCapacity> 158 static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector) 159 { 160 if (size_t size = vector.size()) { 161 ASSERT(vector.data()); 162 return adoptRef(new UStringImpl(vector.releaseBuffer(), size)); 163 } 164 return empty(); 165 } 166 167 SharedUChar* sharedBuffer(); 168 const UChar* characters() const { return m_data; } 169 170 size_t cost() 171 { 172 // For substrings, return the cost of the base string. 173 if (bufferOwnership() == BufferSubstring) 174 return m_substringBuffer->cost(); 175 176 if (m_refCountAndFlags & s_refCountFlagShouldReportedCost) { 177 m_refCountAndFlags &= ~s_refCountFlagShouldReportedCost; 178 return m_length; 179 } 180 return 0; 181 } 182 183 bool isIdentifier() const { return m_refCountAndFlags & s_refCountFlagIsIdentifier; } 184 void setIsIdentifier(bool isIdentifier) 185 { 186 ASSERT(!isStatic()); 187 if (isIdentifier) 188 m_refCountAndFlags |= s_refCountFlagIsIdentifier; 189 else 190 m_refCountAndFlags &= ~s_refCountFlagIsIdentifier; 191 } 192 193 unsigned hash() const { if (!m_hash) m_hash = computeHash(m_data, m_length); return m_hash; } 194 unsigned existingHash() const { ASSERT(m_hash); return m_hash; } 195 static unsigned computeHash(const UChar* data, unsigned length) { return WTF::stringHash(data, length); } 196 static unsigned computeHash(const char* data, unsigned length) { return WTF::stringHash(data, length); } 197 static unsigned computeHash(const char* data) { return WTF::stringHash(data); } 198 199 ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic))) delete this; } 200 201 static UStringImpl* empty(); 202 203 static void copyChars(UChar* destination, const UChar* source, unsigned numCharacters) 204 { 205 if (numCharacters <= s_copyCharsInlineCutOff) { 206 for (unsigned i = 0; i < numCharacters; ++i) 207 destination[i] = source[i]; 208 } else 209 memcpy(destination, source, numCharacters * sizeof(UChar)); 210 } 211 212 private: 213 // This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings. 214 static const unsigned s_copyCharsInlineCutOff = 20; 215 216 BufferOwnership bufferOwnership() const { return static_cast<BufferOwnership>(m_refCountAndFlags & s_refCountMaskBufferOwnership); } 217 bool isStatic() const { return m_refCountAndFlags & s_refCountFlagStatic; } 218 219 const UChar* m_data; 220 union { 221 void* m_buffer; 222 UStringImpl* m_substringBuffer; 223 SharedUChar* m_sharedBuffer; 224 }; 225 mutable unsigned m_hash; 226 }; 227 228 bool equal(const UStringImpl*, const UStringImpl*); 229 230 } 26 // FIXME: Remove this redundant name! 27 #include <wtf/text/StringImpl.h> 28 namespace JSC { typedef WebCore::StringImpl UStringImpl; } 231 29 232 30 #endif
Note:
See TracChangeset
for help on using the changeset viewer.