Remove code duplication from StringImpl create()/reallocate() methods
authormikhail.pozdnyakov@intel.com <mikhail.pozdnyakov@intel.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Jul 2013 15:38:49 +0000 (15:38 +0000)
committermikhail.pozdnyakov@intel.com <mikhail.pozdnyakov@intel.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 3 Jul 2013 15:38:49 +0000 (15:38 +0000)
https://bugs.webkit.org/show_bug.cgi?id=118355

Reviewed by Anders Carlsson.

StringImpl create()/reallocate() methods accepting LChar and UChar used to have
duplicated code. The code duplication is removed now via used templates.

* wtf/text/StringImpl.cpp:
(WTF::StringImpl::constructInternal):
(WTF::LChar):
(WTF::StringImpl::createUninitializedInternal):
(WTF::StringImpl::createUninitialized):
(WTF::StringImpl::reallocateInternal):
(WTF::StringImpl::reallocate):
(WTF::StringImpl::createInternal):
(WTF::StringImpl::create):
* wtf/text/StringImpl.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@152356 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WTF/ChangeLog
Source/WTF/wtf/text/StringImpl.cpp
Source/WTF/wtf/text/StringImpl.h

index 1a908ff..0a7a7b0 100644 (file)
@@ -1,3 +1,24 @@
+2013-07-03  Mikhail Pozdnyakov  <mikhail.pozdnyakov@intel.com>
+
+        Remove code duplication from StringImpl create()/reallocate() methods
+        https://bugs.webkit.org/show_bug.cgi?id=118355
+
+        Reviewed by Anders Carlsson.
+
+        StringImpl create()/reallocate() methods accepting LChar and UChar used to have
+        duplicated code. The code duplication is removed now via used templates.
+
+        * wtf/text/StringImpl.cpp:
+        (WTF::StringImpl::constructInternal):
+        (WTF::LChar):
+        (WTF::StringImpl::createUninitializedInternal):
+        (WTF::StringImpl::createUninitialized):
+        (WTF::StringImpl::reallocateInternal):
+        (WTF::StringImpl::reallocate):
+        (WTF::StringImpl::createInternal):
+        (WTF::StringImpl::create):
+        * wtf/text/StringImpl.h:
+
 2013-07-03  Csaba Osztrogon√°c  <ossy@webkit.org>
 
         Fix cast-align warnings in FastMalloc.cpp
index 8462631..f507404 100644 (file)
@@ -182,7 +182,20 @@ PassRefPtr<StringImpl> StringImpl::createWithoutCopying(const LChar* characters,
     return adoptRef(new StringImpl(characters, length, ConstructWithoutCopying));
 }
 
-PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, LChar*& data)
+template <typename CharType>
+inline PassRefPtr<StringImpl> StringImpl::constructInternal(StringImpl* stringImpl, unsigned length)
+{
+    return adoptRef(new (NotNull, stringImpl) StringImpl(length));
+}
+
+template <>
+inline PassRefPtr<StringImpl> StringImpl::constructInternal<LChar>(StringImpl* stringImpl, unsigned length)
+{
+    return adoptRef(new (NotNull, stringImpl) StringImpl(length, Force8BitConstructor));
+}
+
+template <typename CharType>
+inline PassRefPtr<StringImpl> StringImpl::createUninitializedInternal(unsigned length, CharType*& data)
 {
     if (!length) {
         data = 0;
@@ -192,35 +205,27 @@ PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, LChar*&
     // Allocate a single buffer large enough to contain the StringImpl
     // struct as well as the data which it contains. This removes one
     // heap allocation from this call.
-    if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(LChar)))
+    if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(CharType)))
         CRASH();
-    size_t size = sizeof(StringImpl) + length * sizeof(LChar);
+    size_t size = sizeof(StringImpl) + length * sizeof(CharType);
     StringImpl* string = static_cast<StringImpl*>(fastMalloc(size));
 
-    data = reinterpret_cast<LChar*>(string + 1);
-    return adoptRef(new (NotNull, string) StringImpl(length, Force8BitConstructor));
+    data = reinterpret_cast<CharType*>(string + 1);
+    return constructInternal<CharType>(string, length);
 }
 
-PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, UChar*& data)
+PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, LChar*& data)
 {
-    if (!length) {
-        data = 0;
-        return empty();
-    }
-
-    // Allocate a single buffer large enough to contain the StringImpl
-    // struct as well as the data which it contains. This removes one 
-    // heap allocation from this call.
-    if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(UChar)))
-        CRASH();
-    size_t size = sizeof(StringImpl) + length * sizeof(UChar);
-    StringImpl* string = static_cast<StringImpl*>(fastMalloc(size));
+    return createUninitializedInternal(length, data);
+}
 
-    data = reinterpret_cast<UChar*>(string + 1);
-    return adoptRef(new (NotNull, string) StringImpl(length));
+PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, UChar*& data)
+{
+    return createUninitializedInternal(length, data);
 }
 
-PassRefPtr<StringImpl> StringImpl::reallocate(PassRefPtr<StringImpl> originalString, unsigned length, LChar*& data)
+template <typename CharType>
+inline PassRefPtr<StringImpl> StringImpl::reallocateInternal(PassRefPtr<StringImpl> originalString, unsigned length, CharType*& data)
 {
     ASSERT(originalString->is8Bit());
     ASSERT(originalString->hasOneRef());
@@ -232,58 +237,46 @@ PassRefPtr<StringImpl> StringImpl::reallocate(PassRefPtr<StringImpl> originalStr
     }
 
     // Same as createUninitialized() except here we use fastRealloc.
-    if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(LChar)))
+    if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(CharType)))
         CRASH();
-    size_t size = sizeof(StringImpl) + length * sizeof(LChar);
+    size_t size = sizeof(StringImpl) + length * sizeof(CharType);
     originalString->~StringImpl();
     StringImpl* string = static_cast<StringImpl*>(fastRealloc(originalString.leakRef(), size));
 
-    data = reinterpret_cast<LChar*>(string + 1);
-    return adoptRef(new (NotNull, string) StringImpl(length, Force8BitConstructor));
+    data = reinterpret_cast<CharType*>(string + 1);
+    return constructInternal<CharType>(string, length);
 }
 
-PassRefPtr<StringImpl> StringImpl::reallocate(PassRefPtr<StringImpl> originalString, unsigned length, UChar*& data)
+PassRefPtr<StringImpl> StringImpl::reallocate(PassRefPtr<StringImpl> originalString, unsigned length, LChar*& data)
 {
-    ASSERT(!originalString->is8Bit());
-    ASSERT(originalString->hasOneRef());
-    ASSERT(originalString->bufferOwnership() == BufferInternal);
-
-    if (!length) {
-        data = 0;
-        return empty();
-    }
-
-    // Same as createUninitialized() except here we use fastRealloc.
-    if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(UChar)))
-        CRASH();
-    size_t size = sizeof(StringImpl) + length * sizeof(UChar);
-    originalString->~StringImpl();
-    StringImpl* string = static_cast<StringImpl*>(fastRealloc(originalString.leakRef(), size));
+    return reallocateInternal(originalString, length, data);
+}
 
-    data = reinterpret_cast<UChar*>(string + 1);
-    return adoptRef(new (NotNull, string) StringImpl(length));
+PassRefPtr<StringImpl> StringImpl::reallocate(PassRefPtr<StringImpl> originalString, unsigned length, UChar*& data)
+{
+    return reallocateInternal(originalString, length, data);
 }
 
-PassRefPtr<StringImpl> StringImpl::create(const UChar* characters, unsigned length)
+template <typename CharType>
+inline PassRefPtr<StringImpl> StringImpl::createInternal(const CharType* characters, unsigned length)
 {
     if (!characters || !length)
         return empty();
 
-    UChar* data;
+    CharType* data;
     RefPtr<StringImpl> string = createUninitialized(length, data);
-    memcpy(data, characters, length * sizeof(UChar));
+    memcpy(data, characters, length * sizeof(CharType));
     return string.release();
 }
 
-PassRefPtr<StringImpl> StringImpl::create(const LChar* characters, unsigned length)
+PassRefPtr<StringImpl> StringImpl::create(const UChar* characters, unsigned length)
 {
-    if (!characters || !length)
-        return empty();
+    return createInternal(characters, length);
+}
 
-    LChar* data;
-    RefPtr<StringImpl> string = createUninitialized(length, data);
-    memcpy(data, characters, length * sizeof(LChar));
-    return string.release();
+PassRefPtr<StringImpl> StringImpl::create(const LChar* characters, unsigned length)
+{
+    return createInternal(characters, length);
 }
 
 PassRefPtr<StringImpl> StringImpl::create8BitIfPossible(const UChar* characters, unsigned length)
index d3ca1ff..f520318 100644 (file)
@@ -770,6 +770,10 @@ private:
     bool isStatic() const { return m_refCount & s_refCountFlagIsStaticString; }
     template <class UCharPredicate> PassRefPtr<StringImpl> stripMatchedCharacters(UCharPredicate);
     template <typename CharType, class UCharPredicate> PassRefPtr<StringImpl> simplifyMatchedCharactersToSpace(UCharPredicate);
+    template <typename CharType> static PassRefPtr<StringImpl> constructInternal(StringImpl*, unsigned);
+    template <typename CharType> static PassRefPtr<StringImpl> createUninitializedInternal(unsigned, CharType*&);
+    template <typename CharType> static PassRefPtr<StringImpl> reallocateInternal(PassRefPtr<StringImpl>, unsigned, CharType*&);
+    template <typename CharType> static PassRefPtr<StringImpl> createInternal(const CharType*, unsigned);
     WTF_EXPORT_STRING_API NEVER_INLINE const UChar* getData16SlowCase() const;
     WTF_EXPORT_PRIVATE NEVER_INLINE unsigned hashSlowCase() const;