Changeset 53416 in webkit
- Timestamp:
- Jan 18, 2010 11:27:50 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r53415 r53416 1 2010-01-15 Gavin Barraclough <barraclough@apple.com> 2 3 Reviewed by Darin Adler. 4 5 https://bugs.webkit.org/show_bug.cgi?id=33731 6 Remove uses of PtrAndFlags from WebCore::StringImpl. 7 8 These break the OS X Leaks tool. Move the management of null-terminated copies 9 out from StringImpl to String, and use a bit stolen from the refCount to hold the 10 'InTable' flag. 11 12 * platform/sql/SQLiteFileSystem.cpp: 13 (WebCore::SQLiteFileSystem::openDatabase): 14 * platform/sql/SQLiteStatement.cpp: 15 (WebCore::SQLiteStatement::prepare): 16 * platform/sql/SQLiteStatement.h: 17 * platform/text/PlatformString.h: 18 * platform/text/String.cpp: 19 (WebCore::String::copyWithNullTermination): 20 * platform/text/StringImpl.cpp: 21 (WebCore::StringImpl::StringImpl): 22 (WebCore::StringImpl::~StringImpl): 23 (WebCore::StringImpl::create): 24 (WebCore::StringImpl::crossThreadString): 25 (WebCore::StringImpl::sharedBuffer): 26 * platform/text/StringImpl.h: 27 (WebCore::StringImpl::inTable): 28 (WebCore::StringImpl::setInTable): 29 1 30 2010-01-18 Chris Marrin <cmarrin@apple.com> 2 31 -
trunk/WebCore/WebCore.base.exp
r53371 r53416 143 143 __ZN7WebCore10StringImplD1Ev 144 144 __ZN7WebCore10StringImplcvP8NSStringEv 145 __ZN7WebCore10StringImpldlEPv146 145 __ZN7WebCore10handCursorEv 147 146 __ZN7WebCore10setCookiesEPNS_8DocumentERKNS_4KURLERKNS_6StringE -
trunk/WebCore/platform/sql/SQLiteFileSystem.cpp
r45487 r53416 50 50 { 51 51 // SQLite expects a null terminator on its UTF-16 strings. 52 String path = fileName; 53 return sqlite3_open16(path.charactersWithNullTermination(), database); 52 OwnArrayPtr<const UChar> path; 53 fileName.copyWithNullTermination(path); 54 return sqlite3_open16(path.get(), database); 54 55 } 55 56 -
trunk/WebCore/platform/sql/SQLiteStatement.cpp
r30087 r53416 64 64 const void* tail; 65 65 LOG(SQLDatabase, "SQL - prepare - %s", m_query.ascii().data()); 66 int error = sqlite3_prepare16_v2(m_database.sqlite3Handle(), m_query.charactersWithNullTermination(), -1, &m_statement, &tail); 66 if (!m_queryWithNullTermination) 67 m_query.copyWithNullTermination(m_queryWithNullTermination); 68 int error = sqlite3_prepare16_v2(m_database.sqlite3Handle(), m_queryWithNullTermination.get(), -1, &m_statement, &tail); 67 69 if (error != SQLITE_OK) 68 70 LOG(SQLDatabase, "sqlite3_prepare16 failed (%i)\n%s\n%s", error, m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Handle())); -
trunk/WebCore/platform/sql/SQLiteStatement.h
r32920 r53416 92 92 SQLiteDatabase& m_database; 93 93 String m_query; 94 OwnArrayPtr<const UChar> m_queryWithNullTermination; 94 95 sqlite3_stmt* m_statement; 95 96 #ifndef NDEBUG -
trunk/WebCore/platform/sql/chromium/SQLiteFileSystemChromium.cpp
r50954 r53416 52 52 { 53 53 if (!ChromiumBridge::sandboxEnabled()) { 54 String path = fileName; 55 return sqlite3_open16(path.charactersWithNullTermination(), database); 54 OwnArrayPtr<const UChar> path; 55 fileName.copyWithNullTermination(path); 56 return sqlite3_open16(path.get(), database); 56 57 } 57 58 -
trunk/WebCore/platform/text/PlatformString.h
r52278 r53416 27 27 28 28 #include "StringImpl.h" 29 #include <wtf/OwnArrayPtr.h> 29 30 30 31 #ifdef __OBJC__ … … 94 95 unsigned length() const; 95 96 const UChar* characters() const; 96 const UChar* charactersWithNullTermination();97 void copyWithNullTermination(OwnArrayPtr<const UChar>&) const; 97 98 98 99 UChar operator[](unsigned i) const; // if i >= length(), returns 0 -
trunk/WebCore/platform/text/String.cpp
r52791 r53416 330 330 } 331 331 332 const UChar* String::charactersWithNullTermination() 333 { 334 if (!m_impl) 335 return 0; 336 if (m_impl->hasTerminatingNullCharacter()) 337 return m_impl->characters(); 338 m_impl = StringImpl::createWithTerminatingNullCharacter(*m_impl); 339 return m_impl->characters(); 332 void String::copyWithNullTermination(OwnArrayPtr<const UChar>& result) const 333 { 334 if (!m_impl) 335 CRASH(); 336 unsigned length = m_impl->length(); 337 UChar* buffer = new UChar[length + 1]; 338 memcpy(buffer, m_impl->characters(), length * sizeof(UChar)); 339 buffer[length] = 0; 340 result.set(buffer); 340 341 } 341 342 -
trunk/WebCore/platform/text/StringImpl.cpp
r52463 r53416 58 58 } 59 59 60 // Some of the factory methods create buffers using fastMalloc.61 // We must ensure that all allocations of StringImpl are allocated using62 // fastMalloc so that we don't have mis-matched frees. We accomplish63 // this by overriding the new and delete operators.64 void* StringImpl::operator new(size_t size, void* address)65 {66 if (address)67 return address; // Allocating using an internal buffer68 return fastMalloc(size);69 }70 71 void* StringImpl::operator new(size_t size)72 {73 return fastMalloc(size);74 }75 76 void StringImpl::operator delete(void* address)77 {78 fastFree(address);79 }80 81 60 // This constructor is used only to create the empty string. 82 61 StringImpl::StringImpl() 83 62 : m_data(0) 63 , m_sharedBuffer(0) 84 64 , m_length(0) 65 , m_refCountAndFlags(s_refCountIncrement) 85 66 , m_hash(0) 86 67 { … … 93 74 inline StringImpl::StringImpl(const UChar* characters, unsigned length) 94 75 : m_data(characters) 76 , m_sharedBuffer(0) 95 77 , m_length(length) 78 , m_refCountAndFlags(s_refCountIncrement) 96 79 , m_hash(0) 97 80 { … … 105 88 AtomicString::remove(this); 106 89 if (!bufferIsInternal()) { 107 SharedUChar* sharedBuffer = m_sharedBuffer AndFlags.get();90 SharedUChar* sharedBuffer = m_sharedBuffer; 108 91 if (sharedBuffer) 109 92 sharedBuffer->deref(); … … 971 954 PassRefPtr<StringImpl> impl = adoptRef(new StringImpl(str.data(), str.size())); 972 955 sharedBuffer->ref(); 973 impl->m_sharedBuffer AndFlags.set(sharedBuffer);956 impl->m_sharedBuffer = sharedBuffer; 974 957 return impl; 975 958 } … … 986 969 } 987 970 #endif 988 989 PassRefPtr<StringImpl> StringImpl::createWithTerminatingNullCharacter(const StringImpl& string)990 {991 // Use createUninitialized instead of 'new StringImpl' so that the string and its buffer992 // get allocated in a single malloc block.993 UChar* data;994 int length = string.m_length;995 RefPtr<StringImpl> terminatedString = createUninitialized(length + 1, data);996 memcpy(data, string.m_data, length * sizeof(UChar));997 data[length] = 0;998 terminatedString->m_length--;999 terminatedString->m_hash = string.m_hash;1000 terminatedString->m_sharedBufferAndFlags.setFlag(HasTerminatingNullCharacter);1001 return terminatedString.release();1002 }1003 971 1004 972 PassRefPtr<StringImpl> StringImpl::threadsafeCopy() const … … 1015 983 if (shared) { 1016 984 RefPtr<StringImpl> impl = adoptRef(new StringImpl(m_data, m_length)); 1017 impl->m_sharedBuffer AndFlags.set(shared->crossThreadCopy().releaseRef());985 impl->m_sharedBuffer = shared->crossThreadCopy().releaseRef(); 1018 986 return impl.release(); 1019 987 } … … 1028 996 return 0; 1029 997 1030 if (!m_sharedBuffer AndFlags.get())1031 m_sharedBuffer AndFlags.set(SharedUChar::create(new OwnFastMallocPtr<UChar>(const_cast<UChar*>(m_data))).releaseRef());1032 return m_sharedBuffer AndFlags.get();998 if (!m_sharedBuffer) 999 m_sharedBuffer = SharedUChar::create(new OwnFastMallocPtr<UChar>(const_cast<UChar*>(m_data))).releaseRef(); 1000 return m_sharedBuffer; 1033 1001 } 1034 1002 -
trunk/WebCore/platform/text/StringImpl.h
r52776 r53416 27 27 #include <wtf/ASCIICType.h> 28 28 #include <wtf/CrossThreadRefCounted.h> 29 #include <wtf/Noncopyable.h> 29 30 #include <wtf/OwnFastMallocPtr.h> 30 #include <wtf/PtrAndFlags.h>31 31 #include <wtf/RefCounted.h> 32 32 #include <wtf/StringHashFunctions.h> … … 59 59 typedef bool (*CharacterMatchFunctionPtr)(UChar); 60 60 61 class StringImpl : public RefCounted<StringImpl>{61 class StringImpl : public Noncopyable { 62 62 friend struct CStringTranslator; 63 63 friend struct HashAndCharactersTranslator; … … 83 83 static PassRefPtr<StringImpl> createUninitialized(unsigned length, UChar*& data); 84 84 85 static PassRefPtr<StringImpl> createWithTerminatingNullCharacter(const StringImpl&);86 87 85 static PassRefPtr<StringImpl> createStrippingNullCharacters(const UChar*, unsigned length); 88 86 static PassRefPtr<StringImpl> adopt(StringBuffer&); … … 97 95 unsigned length() { return m_length; } 98 96 99 bool hasTerminatingNullCharacter() const { return m_sharedBufferAndFlags.isFlagSet(HasTerminatingNullCharacter); } 100 101 bool inTable() const { return m_sharedBufferAndFlags.isFlagSet(InTable); } 102 void setInTable() { return m_sharedBufferAndFlags.setFlag(InTable); } 97 bool inTable() const { return m_refCountAndFlags & s_refCountFlagInTable; } 98 void setInTable() { m_refCountAndFlags |= s_refCountFlagInTable; } 103 99 104 100 unsigned hash() { if (m_hash == 0) m_hash = computeHash(m_data, m_length); return m_hash; } … … 107 103 inline static unsigned computeHash(const char* data) { return WTF::stringHash(data); } 108 104 105 StringImpl* ref() { m_refCountAndFlags += s_refCountIncrement; return this; } 106 ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & s_refCountMask)) delete this; } 107 ALWAYS_INLINE bool hasOneRef() const { return (m_refCountAndFlags & s_refCountMask) == s_refCountIncrement; } 108 109 109 // Returns a StringImpl suitable for use on another thread. 110 110 PassRefPtr<StringImpl> crossThreadString(); … … 176 176 #endif 177 177 178 void operator delete(void*);179 180 178 private: 181 // Allocation from a custom buffer is only allowed internally to avoid 182 // mismatched allocators. Callers should use create(). 183 void* operator new(size_t size); 184 void* operator new(size_t size, void* address); 179 using Noncopyable::operator new; 180 void* operator new(size_t, void* inPlace) { ASSERT(inPlace); return inPlace; } 185 181 186 182 static PassRefPtr<StringImpl> createStrippingNullCharactersSlowCase(const UChar*, unsigned length); … … 190 186 bool bufferIsInternal() { return m_data == reinterpret_cast<const UChar*>(this + 1); } 191 187 192 enum StringImplFlags { 193 HasTerminatingNullCharacter, 194 InTable, 195 }; 188 static const unsigned s_refCountMask = 0xFFFFFFFE; 189 static const unsigned s_refCountIncrement = 0x2; 190 static const unsigned s_refCountFlagInTable = 0x1; 196 191 197 192 const UChar* m_data; 193 SharedUChar* m_sharedBuffer; 198 194 unsigned m_length; 195 unsigned m_refCountAndFlags; 199 196 mutable unsigned m_hash; 200 PtrAndFlags<SharedUChar, StringImplFlags> m_sharedBufferAndFlags;201 197 // There is a fictitious variable-length UChar array at the end, which is used 202 198 // as the internal buffer by the createUninitialized and create methods. -
trunk/WebCore/storage/OriginUsageRecord.cpp
r47808 r53416 43 43 { 44 44 ASSERT(!m_databaseMap.contains(identifier)); 45 ASSERT_ARG(identifier, identifier.impl()-> refCount() == 1);46 ASSERT_ARG(fullPath, fullPath.impl()-> refCount() == 1);45 ASSERT_ARG(identifier, identifier.impl()->hasOneRef()); 46 ASSERT_ARG(fullPath, fullPath.impl()->hasOneRef()); 47 47 48 48 m_databaseMap.set(identifier, DatabaseEntry(fullPath)); … … 64 64 { 65 65 ASSERT(m_databaseMap.contains(identifier)); 66 ASSERT_ARG(identifier, identifier.impl()-> refCount() == 1);66 ASSERT_ARG(identifier, identifier.impl()->hasOneRef()); 67 67 68 68 m_unknownSet.add(identifier);
Note: See TracChangeset
for help on using the changeset viewer.