diff options
Diffstat (limited to 'JavaScriptCore/wtf/text')
-rw-r--r-- | JavaScriptCore/wtf/text/AtomicString.cpp | 39 | ||||
-rw-r--r-- | JavaScriptCore/wtf/text/AtomicString.h | 10 | ||||
-rw-r--r-- | JavaScriptCore/wtf/text/CString.cpp | 10 | ||||
-rw-r--r-- | JavaScriptCore/wtf/text/CString.h | 10 | ||||
-rw-r--r-- | JavaScriptCore/wtf/text/StringImpl.cpp | 14 | ||||
-rw-r--r-- | JavaScriptCore/wtf/text/StringImpl.h | 12 | ||||
-rw-r--r-- | JavaScriptCore/wtf/text/StringStatics.cpp | 80 | ||||
-rw-r--r-- | JavaScriptCore/wtf/text/WTFString.cpp | 47 | ||||
-rw-r--r-- | JavaScriptCore/wtf/text/WTFString.h | 46 |
9 files changed, 147 insertions, 121 deletions
diff --git a/JavaScriptCore/wtf/text/AtomicString.cpp b/JavaScriptCore/wtf/text/AtomicString.cpp index ab52488..0547b8c 100644 --- a/JavaScriptCore/wtf/text/AtomicString.cpp +++ b/JavaScriptCore/wtf/text/AtomicString.cpp @@ -20,13 +20,8 @@ #include "config.h" -#ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC -#define ATOMICSTRING_HIDE_GLOBALS 1 -#endif - #include "AtomicString.h" -#include "StaticConstructors.h" #include "StringHash.h" #include <wtf/HashSet.h> #include <wtf/Threading.h> @@ -34,6 +29,8 @@ namespace WebCore { +COMPILE_ASSERT(sizeof(AtomicString) == sizeof(String), atomic_string_and_string_must_be_same_size); + class AtomicStringTable { public: static AtomicStringTable* create() @@ -255,14 +252,14 @@ PassRefPtr<StringImpl> AtomicString::add(const UChar* s) return addResult.second ? adoptRef(*addResult.first) : *addResult.first; } -PassRefPtr<StringImpl> AtomicString::add(StringImpl* r) +PassRefPtr<StringImpl> AtomicString::addSlowCase(StringImpl* r) { if (!r || r->isAtomic()) return r; if (r->length() == 0) return StringImpl::empty(); - + StringImpl* result = *stringTable().add(r).first; if (result == r) r->setIsAtomic(true); @@ -299,32 +296,4 @@ AtomicString AtomicString::lower() const return AtomicString(newImpl); } -JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, nullAtom) -JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, emptyAtom, "") -JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, textAtom, "#text") -JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, commentAtom, "#comment") -JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, starAtom, "*") -JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, xmlAtom, "xml") -JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, xmlnsAtom, "xmlns") - -void AtomicString::init() -{ - static bool initialized; - if (!initialized) { - // Initialization is not thread safe, so this function must be called from the main thread first. - ASSERT(isMainThread()); - - // Use placement new to initialize the globals. - new ((void*)&nullAtom) AtomicString; - new ((void*)&emptyAtom) AtomicString(""); - new ((void*)&textAtom) AtomicString("#text"); - new ((void*)&commentAtom) AtomicString("#comment"); - new ((void*)&starAtom) AtomicString("*"); - new ((void*)&xmlAtom) AtomicString("xml"); - new ((void*)&xmlnsAtom) AtomicString("xmlns"); - - initialized = true; - } -} - } diff --git a/JavaScriptCore/wtf/text/AtomicString.h b/JavaScriptCore/wtf/text/AtomicString.h index 9db70f4..5bb2cf9 100644 --- a/JavaScriptCore/wtf/text/AtomicString.h +++ b/JavaScriptCore/wtf/text/AtomicString.h @@ -38,7 +38,7 @@ namespace WebCore { struct AtomicStringHash; -class AtomicString : public FastAllocBase { +class AtomicString { public: static void init(); @@ -117,7 +117,13 @@ private: static PassRefPtr<StringImpl> add(const UChar*, unsigned length); static PassRefPtr<StringImpl> add(const UChar*, unsigned length, unsigned existingHash); static PassRefPtr<StringImpl> add(const UChar*); - static PassRefPtr<StringImpl> add(StringImpl*); + ALWAYS_INLINE PassRefPtr<StringImpl> add(StringImpl* r) + { + if (!r || r->isAtomic()) + return r; + return addSlowCase(r); + } + static PassRefPtr<StringImpl> addSlowCase(StringImpl*); }; inline bool operator==(const AtomicString& a, const AtomicString& b) { return a.impl() == b.impl(); } diff --git a/JavaScriptCore/wtf/text/CString.cpp b/JavaScriptCore/wtf/text/CString.cpp index d93a5a3..7d09f12 100644 --- a/JavaScriptCore/wtf/text/CString.cpp +++ b/JavaScriptCore/wtf/text/CString.cpp @@ -51,11 +51,6 @@ void CString::init(const char* str, unsigned length) m_buffer->mutableData()[length] = '\0'; } -const char* CString::data() const -{ - return m_buffer ? m_buffer->data() : 0; -} - char* CString::mutableData() { copyBufferIfNeeded(); @@ -64,11 +59,6 @@ char* CString::mutableData() return m_buffer->mutableData(); } -unsigned CString::length() const -{ - return m_buffer ? m_buffer->length() - 1 : 0; -} - CString CString::newUninitialized(size_t length, char*& characterBuffer) { CString result; diff --git a/JavaScriptCore/wtf/text/CString.h b/JavaScriptCore/wtf/text/CString.h index 47f7675..d8250c5 100644 --- a/JavaScriptCore/wtf/text/CString.h +++ b/JavaScriptCore/wtf/text/CString.h @@ -57,9 +57,15 @@ public: CString(CStringBuffer* buffer) : m_buffer(buffer) { } static CString newUninitialized(size_t length, char*& characterBuffer); - const char* data() const; + const char* data() const + { + return m_buffer ? m_buffer->data() : 0; + } char* mutableData(); - unsigned length() const; + unsigned length() const + { + return m_buffer ? m_buffer->length() - 1 : 0; + } bool isNull() const { return !m_buffer; } diff --git a/JavaScriptCore/wtf/text/StringImpl.cpp b/JavaScriptCore/wtf/text/StringImpl.cpp index ff69737..68ff456 100644 --- a/JavaScriptCore/wtf/text/StringImpl.cpp +++ b/JavaScriptCore/wtf/text/StringImpl.cpp @@ -66,20 +66,6 @@ StringImpl::~StringImpl() } } -StringImpl* StringImpl::empty() -{ - // FIXME: This works around a bug in our port of PCRE, that a regular expression - // run on the empty string may still perform a read from the first element, and - // as such we need this to be a valid pointer. No code should ever be reading - // from a zero length string, so this should be able to be a non-null pointer - // into the zero-page. - // Replace this with 'reinterpret_cast<UChar*>(static_cast<intptr_t>(1))' once - // PCRE goes away. - static UChar emptyUCharData = 0; - DEFINE_STATIC_LOCAL(StringImpl, emptyString, (&emptyUCharData, 0, ConstructStaticString)); - return &emptyString; -} - PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, UChar*& data) { if (!length) { diff --git a/JavaScriptCore/wtf/text/StringImpl.h b/JavaScriptCore/wtf/text/StringImpl.h index dbf51e3..f4b2970 100644 --- a/JavaScriptCore/wtf/text/StringImpl.h +++ b/JavaScriptCore/wtf/text/StringImpl.h @@ -151,7 +151,7 @@ public: static PassRefPtr<StringImpl> create(const char*, unsigned length); static PassRefPtr<StringImpl> create(const char*); static PassRefPtr<StringImpl> create(const UChar*, unsigned length, PassRefPtr<SharedUChar> sharedBuffer); - static PassRefPtr<StringImpl> create(PassRefPtr<StringImpl> rep, unsigned offset, unsigned length) + static ALWAYS_INLINE PassRefPtr<StringImpl> create(PassRefPtr<StringImpl> rep, unsigned offset, unsigned length) { ASSERT(rep); ASSERT(length <= rep->length()); @@ -164,18 +164,22 @@ public: } static PassRefPtr<StringImpl> createUninitialized(unsigned length, UChar*& data); - static PassRefPtr<StringImpl> tryCreateUninitialized(unsigned length, UChar*& output) + static ALWAYS_INLINE PassRefPtr<StringImpl> tryCreateUninitialized(unsigned length, UChar*& output) { if (!length) { output = 0; return empty(); } - if (length > ((std::numeric_limits<size_t>::max() - sizeof(StringImpl)) / sizeof(UChar))) + if (length > ((std::numeric_limits<size_t>::max() - sizeof(StringImpl)) / sizeof(UChar))) { + output = 0; return 0; + } StringImpl* resultImpl; - if (!tryFastMalloc(sizeof(UChar) * length + sizeof(StringImpl)).getValue(resultImpl)) + if (!tryFastMalloc(sizeof(UChar) * length + sizeof(StringImpl)).getValue(resultImpl)) { + output = 0; return 0; + } output = reinterpret_cast<UChar*>(resultImpl + 1); return adoptRef(new(resultImpl) StringImpl(length)); } diff --git a/JavaScriptCore/wtf/text/StringStatics.cpp b/JavaScriptCore/wtf/text/StringStatics.cpp new file mode 100644 index 0000000..4a23a16 --- /dev/null +++ b/JavaScriptCore/wtf/text/StringStatics.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2010 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC +#define ATOMICSTRING_HIDE_GLOBALS 1 +#endif + +#include "AtomicString.h" +#include "StaticConstructors.h" +#include "StringImpl.h" + +namespace WebCore { + +StringImpl* StringImpl::empty() +{ + // FIXME: This works around a bug in our port of PCRE, that a regular expression + // run on the empty string may still perform a read from the first element, and + // as such we need this to be a valid pointer. No code should ever be reading + // from a zero length string, so this should be able to be a non-null pointer + // into the zero-page. + // Replace this with 'reinterpret_cast<UChar*>(static_cast<intptr_t>(1))' once + // PCRE goes away. + static UChar emptyUCharData = 0; + DEFINE_STATIC_LOCAL(StringImpl, emptyString, (&emptyUCharData, 0, ConstructStaticString)); + return &emptyString; +} + +JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, nullAtom) +JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, emptyAtom, "") +JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, textAtom, "#text") +JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, commentAtom, "#comment") +JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, starAtom, "*") +JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, xmlAtom, "xml") +JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, xmlnsAtom, "xmlns") + +void AtomicString::init() +{ + static bool initialized; + if (!initialized) { + // Initialization is not thread safe, so this function must be called from the main thread first. + ASSERT(isMainThread()); + + // Use placement new to initialize the globals. + new ((void*)&nullAtom) AtomicString; + new ((void*)&emptyAtom) AtomicString(""); + new ((void*)&textAtom) AtomicString("#text"); + new ((void*)&commentAtom) AtomicString("#comment"); + new ((void*)&starAtom) AtomicString("*"); + new ((void*)&xmlAtom) AtomicString("xml"); + new ((void*)&xmlnsAtom) AtomicString("xmlns"); + + initialized = true; + } +} + +} diff --git a/JavaScriptCore/wtf/text/WTFString.cpp b/JavaScriptCore/wtf/text/WTFString.cpp index a683e3d..842d755 100644 --- a/JavaScriptCore/wtf/text/WTFString.cpp +++ b/JavaScriptCore/wtf/text/WTFString.cpp @@ -37,13 +37,6 @@ using namespace WTF::Unicode; namespace WebCore { -String::String(const UChar* str, unsigned len) -{ - if (!str) - return; - m_impl = StringImpl::create(str, len); -} - String::String(const UChar* str) { if (!str) @@ -56,20 +49,6 @@ String::String(const UChar* str) m_impl = StringImpl::create(str, len); } -String::String(const char* str) -{ - if (!str) - return; - m_impl = StringImpl::create(str); -} - -String::String(const char* str, unsigned length) -{ - if (!str) - return; - m_impl = StringImpl::create(str, length); -} - void String::append(const String& str) { if (str.isEmpty()) @@ -202,13 +181,6 @@ void String::insert(const UChar* charactersToInsert, unsigned lengthToInsert, un m_impl = newImpl.release(); } -UChar String::operator[](unsigned i) const -{ - if (!m_impl || i >= m_impl->length()) - return 0; - return m_impl->characters()[i]; -} - UChar32 String::characterStartingAt(unsigned i) const { if (!m_impl || i >= m_impl->length()) @@ -216,13 +188,6 @@ UChar32 String::characterStartingAt(unsigned i) const return m_impl->characterStartingAt(i); } -unsigned String::length() const -{ - if (!m_impl) - return 0; - return m_impl->length(); -} - void String::truncate(unsigned position) { if (position >= length()) @@ -311,13 +276,6 @@ bool String::percentage(int& result) const return true; } -const UChar* String::characters() const -{ - if (!m_impl) - return 0; - return m_impl->characters(); -} - const UChar* String::charactersWithNullTermination() { if (!m_impl) @@ -591,11 +549,6 @@ String String::crossThreadString() const return m_impl->crossThreadString(); } -bool String::isEmpty() const -{ - return !m_impl || !m_impl->length(); -} - void String::split(const String& separator, bool allowEmptyEntries, Vector<String>& result) const { result.clear(); diff --git a/JavaScriptCore/wtf/text/WTFString.h b/JavaScriptCore/wtf/text/WTFString.h index 7c3c2dd..d98621c 100644 --- a/JavaScriptCore/wtf/text/WTFString.h +++ b/JavaScriptCore/wtf/text/WTFString.h @@ -86,10 +86,25 @@ int reverseFind(const UChar*, size_t, UChar, int startPosition = -1); class String { public: String() { } // gives null string, distinguishable from an empty string - String(const UChar*, unsigned length); + String(const UChar* str, unsigned len) + { + if (!str) + return; + m_impl = StringImpl::create(str, len); + } + String(const char* str) + { + if (!str) + return; + m_impl = StringImpl::create(str); + } + String(const char* str, unsigned length) + { + if (!str) + return; + m_impl = StringImpl::create(str, length); + } String(const UChar*); // Specifically for null terminated UTF-16 - String(const char*); - String(const char*, unsigned length); String(StringImpl* i) : m_impl(i) { } String(PassRefPtr<StringImpl> i) : m_impl(i) { } String(RefPtr<StringImpl> i) : m_impl(i) { } @@ -103,11 +118,28 @@ public: static String adopt(StringBuffer& buffer) { return StringImpl::adopt(buffer); } static String adopt(Vector<UChar>& vector) { return StringImpl::adopt(vector); } - unsigned length() const; - const UChar* characters() const; + ALWAYS_INLINE unsigned length() const + { + if (!m_impl) + return 0; + return m_impl->length(); + } + + const UChar* characters() const + { + if (!m_impl) + return 0; + return m_impl->characters(); + } + const UChar* charactersWithNullTermination(); - UChar operator[](unsigned i) const; // if i >= length(), returns 0 + UChar operator[](unsigned i) const // if i >= length(), returns 0 + { + if (!m_impl || i >= m_impl->length()) + return 0; + return m_impl->characters()[i]; + } UChar32 characterStartingAt(unsigned) const; // Ditto. bool contains(UChar c) const { return find(c) != -1; } @@ -215,7 +247,7 @@ public: String threadsafeCopy() const; bool isNull() const { return !m_impl; } - bool isEmpty() const; + ALWAYS_INLINE bool isEmpty() const { return !m_impl || !m_impl->length(); } StringImpl* impl() const { return m_impl.get(); } |