From 0f5d4355d7a384679722338d55f65bbb92350cfc Mon Sep 17 00:00:00 2001 From: Naiem Shaik Date: Thu, 19 Jul 2012 10:45:56 -0700 Subject: DOM Optimizations DOM traversal optimizations DOM Core optimizations Prefetch optimization for DOM Tree Traversal Conflicts: Source/WebKit/android/jni/WebViewCore.cpp Change-Id: Icbb8a7229ee9cff1a5401b57c8181f18b9a6d6e0 --- Source/JavaScriptCore/wtf/RefPtr.h | 2 +- Source/JavaScriptCore/wtf/text/AtomicString.cpp | 2 +- Source/JavaScriptCore/wtf/text/AtomicString.h | 2 +- Source/JavaScriptCore/wtf/text/StringImpl.cpp | 10 +++-- Source/JavaScriptCore/wtf/text/StringImpl.h | 39 +++++++----------- Source/JavaScriptCore/wtf/text/StringImplBase.h | 55 +++++++++++++++---------- Source/JavaScriptCore/wtf/text/WTFString.h | 2 +- 7 files changed, 59 insertions(+), 53 deletions(-) (limited to 'Source/JavaScriptCore/wtf') diff --git a/Source/JavaScriptCore/wtf/RefPtr.h b/Source/JavaScriptCore/wtf/RefPtr.h index 353bd35..aaa4a8e 100644 --- a/Source/JavaScriptCore/wtf/RefPtr.h +++ b/Source/JavaScriptCore/wtf/RefPtr.h @@ -57,7 +57,7 @@ namespace WTF { ALWAYS_INLINE ~RefPtr() { derefIfNotNull(m_ptr); } - T* get() const { return m_ptr; } + ALWAYS_INLINE T* get() const { return m_ptr; } void clear(); PassRefPtr release() { PassRefPtr tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; } diff --git a/Source/JavaScriptCore/wtf/text/AtomicString.cpp b/Source/JavaScriptCore/wtf/text/AtomicString.cpp index 9dd655e..3c02607 100644 --- a/Source/JavaScriptCore/wtf/text/AtomicString.cpp +++ b/Source/JavaScriptCore/wtf/text/AtomicString.cpp @@ -343,7 +343,7 @@ AtomicString AtomicString::lower() const { // Note: This is a hot function in the Dromaeo benchmark. StringImpl* impl = this->impl(); - if (UNLIKELY(!impl)) + if (UNLIKELY(!impl) || impl->isLower()) return *this; RefPtr newImpl = impl->lower(); if (LIKELY(newImpl == impl)) diff --git a/Source/JavaScriptCore/wtf/text/AtomicString.h b/Source/JavaScriptCore/wtf/text/AtomicString.h index 440700c..5ee9e5d 100644 --- a/Source/JavaScriptCore/wtf/text/AtomicString.h +++ b/Source/JavaScriptCore/wtf/text/AtomicString.h @@ -58,7 +58,7 @@ public: operator const String&() const { return m_string; } const String& string() const { return m_string; }; - AtomicStringImpl* impl() const { return static_cast(m_string.impl()); } + ALWAYS_INLINE AtomicStringImpl* impl() const { return static_cast(m_string.impl()); } const UChar* characters() const { return m_string.characters(); } unsigned length() const { return m_string.length(); } diff --git a/Source/JavaScriptCore/wtf/text/StringImpl.cpp b/Source/JavaScriptCore/wtf/text/StringImpl.cpp index 9afd1d2..826e749 100644 --- a/Source/JavaScriptCore/wtf/text/StringImpl.cpp +++ b/Source/JavaScriptCore/wtf/text/StringImpl.cpp @@ -148,7 +148,7 @@ SharedUChar* StringImpl::sharedBuffer() if (ownership == BufferOwned) { ASSERT(!m_sharedBuffer); m_sharedBuffer = SharedUChar::create(new SharableUChar(m_data)).leakRef(); - m_refCountAndFlags = (m_refCountAndFlags & ~s_refCountMaskBufferOwnership) | BufferShared; + m_bufferOwnership = BufferShared; } ASSERT(bufferOwnership() == BufferShared); @@ -193,6 +193,8 @@ PassRefPtr StringImpl::lower() { // Note: This is a hot function in the Dromaeo benchmark, specifically the // no-op code path up through the first 'return' statement. + if (isLower()) + return this; // First scan the string for uppercase and non-ASCII characters: UChar ored = 0; @@ -205,8 +207,10 @@ PassRefPtr StringImpl::lower() } // Nothing to do if the string is all ASCII with no uppercase. - if (noUpper && !(ored & ~0x7F)) + if (noUpper && !(ored & ~0x7F)) { + setIsLower(true); return this; + } if (m_length > static_cast(numeric_limits::max())) CRASH(); @@ -1060,7 +1064,7 @@ PassRefPtr StringImpl::createWithTerminatingNullCharacter(const Stri data[length] = 0; terminatedString->m_length--; terminatedString->m_hash = string.m_hash; - terminatedString->m_refCountAndFlags |= s_refCountFlagHasTerminatingNullCharacter; + terminatedString->m_hasTerminatingNullCharacter = true; return terminatedString.release(); } diff --git a/Source/JavaScriptCore/wtf/text/StringImpl.h b/Source/JavaScriptCore/wtf/text/StringImpl.h index 81911b3..bd51f78 100644 --- a/Source/JavaScriptCore/wtf/text/StringImpl.h +++ b/Source/JavaScriptCore/wtf/text/StringImpl.h @@ -206,40 +206,29 @@ public: if (bufferOwnership() == BufferSubstring) return m_substringBuffer->cost(); - if (m_refCountAndFlags & s_refCountFlagShouldReportedCost) { - m_refCountAndFlags &= ~s_refCountFlagShouldReportedCost; + if (m_shouldReportCost) { + m_shouldReportCost = false; return m_length; } return 0; } - bool isIdentifier() const { return m_refCountAndFlags & s_refCountFlagIsIdentifier; } - void setIsIdentifier(bool isIdentifier) - { - ASSERT(!isStatic()); - if (isIdentifier) - m_refCountAndFlags |= s_refCountFlagIsIdentifier; - else - m_refCountAndFlags &= ~s_refCountFlagIsIdentifier; - } + bool isIdentifier() const { return m_identifier; } + void setIsIdentifier(bool isIdentifier) { ASSERT(!isStatic()); m_identifier = isIdentifier; } - bool hasTerminatingNullCharacter() const { return m_refCountAndFlags & s_refCountFlagHasTerminatingNullCharacter; } + bool hasTerminatingNullCharacter() const { return m_hasTerminatingNullCharacter; } - bool isAtomic() const { return m_refCountAndFlags & s_refCountFlagIsAtomic; } - void setIsAtomic(bool isIdentifier) - { - ASSERT(!isStatic()); - if (isIdentifier) - m_refCountAndFlags |= s_refCountFlagIsAtomic; - else - m_refCountAndFlags &= ~s_refCountFlagIsAtomic; - } + bool isAtomic() const { return m_atomic; } + void setIsAtomic(bool isAtomic) { ASSERT(!isStatic()); m_atomic = isAtomic; } + + bool isLower() const { return m_lower; } + void setIsLower(bool isLower) { m_lower = isLower; } unsigned hash() const { if (!m_hash) m_hash = StringHasher::computeHash(m_data, m_length); return m_hash; } unsigned existingHash() const { ASSERT(m_hash); return m_hash; } - ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic))) delete this; } - ALWAYS_INLINE bool hasOneRef() const { return (m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic)) == s_refCountIncrement; } + ALWAYS_INLINE void deref() { --m_refCount; if (!m_refCount && !m_static) delete this; } + ALWAYS_INLINE bool hasOneRef() const { return (m_refCount == 1 && !m_static); } static StringImpl* empty(); @@ -328,8 +317,8 @@ private: static PassRefPtr createStrippingNullCharactersSlowCase(const UChar*, unsigned length); - BufferOwnership bufferOwnership() const { return static_cast(m_refCountAndFlags & s_refCountMaskBufferOwnership); } - bool isStatic() const { return m_refCountAndFlags & s_refCountFlagStatic; } + BufferOwnership bufferOwnership() const { return static_cast(m_bufferOwnership); } + bool isStatic() const { return m_static; } const UChar* m_data; union { void* m_buffer; diff --git a/Source/JavaScriptCore/wtf/text/StringImplBase.h b/Source/JavaScriptCore/wtf/text/StringImplBase.h index 26bc1d9..b6a7210 100644 --- a/Source/JavaScriptCore/wtf/text/StringImplBase.h +++ b/Source/JavaScriptCore/wtf/text/StringImplBase.h @@ -33,9 +33,9 @@ namespace WTF { class StringImplBase { WTF_MAKE_NONCOPYABLE(StringImplBase); WTF_MAKE_FAST_ALLOCATED; public: - bool isStringImpl() { return (m_refCountAndFlags & s_refCountInvalidForStringImpl) != s_refCountInvalidForStringImpl; } + bool isStringImpl() { return !(m_static && m_shouldReportCost); } unsigned length() const { return m_length; } - void ref() { m_refCountAndFlags += s_refCountIncrement; } + void ref() { ++m_refCount; } protected: enum BufferOwnership { @@ -49,7 +49,14 @@ protected: StringImplBase() { } StringImplBase(unsigned length, BufferOwnership ownership) - : m_refCountAndFlags(s_refCountIncrement | s_refCountFlagShouldReportedCost | ownership) + : m_lower(false) + , m_hasTerminatingNullCharacter(false) + , m_atomic(false) + , m_static(false) + , m_shouldReportCost(true) + , m_identifier(false) + , m_bufferOwnership(ownership) + , m_refCount(1) , m_length(length) { ASSERT(isStringImpl()); @@ -57,7 +64,14 @@ protected: enum StaticStringConstructType { ConstructStaticString }; StringImplBase(unsigned length, StaticStringConstructType) - : m_refCountAndFlags(s_refCountFlagStatic | s_refCountFlagIsIdentifier | BufferOwned) + : m_lower(false) + , m_hasTerminatingNullCharacter(false) + , m_atomic(false) + , m_static(true) + , m_shouldReportCost(false) + , m_identifier(true) + , m_bufferOwnership(BufferOwned) + , m_refCount(0) , m_length(length) { ASSERT(isStringImpl()); @@ -67,29 +81,28 @@ protected: // and sets the flags into a state marking the object as such. enum NonStringImplConstructType { ConstructNonStringImpl }; StringImplBase(NonStringImplConstructType) - : m_refCountAndFlags(s_refCountIncrement | s_refCountInvalidForStringImpl) + : m_lower(false) + , m_hasTerminatingNullCharacter(false) + , m_atomic(false) + , m_static(true) + , m_shouldReportCost(true) + , m_identifier(false) + , m_bufferOwnership(0) + , m_refCount(1) , m_length(0) { ASSERT(!isStringImpl()); } - // The bottom 7 bits hold flags, the top 25 bits hold the ref count. - // When dereferencing StringImpls we check for the ref count AND the - // static bit both being zero - static strings are never deleted. - static const unsigned s_refCountMask = 0xFFFFFF80; - static const unsigned s_refCountIncrement = 0x80; - static const unsigned s_refCountFlagStatic = 0x40; - static const unsigned s_refCountFlagHasTerminatingNullCharacter = 0x20; - static const unsigned s_refCountFlagIsAtomic = 0x10; - static const unsigned s_refCountFlagShouldReportedCost = 0x8; - static const unsigned s_refCountFlagIsIdentifier = 0x4; - static const unsigned s_refCountMaskBufferOwnership = 0x3; - // An invalid permutation of flags (static & shouldReportedCost - static strings do not - // set shouldReportedCost in the constructor, and this bit is only ever cleared, not set). - // Used by "ConstructNonStringImpl" constructor, above. - static const unsigned s_refCountInvalidForStringImpl = s_refCountFlagStatic | s_refCountFlagShouldReportedCost; + bool m_lower : 1; + bool m_hasTerminatingNullCharacter : 1; + bool m_atomic : 1; + bool m_static : 1; + bool m_shouldReportCost : 1; + bool m_identifier : 1; + unsigned m_bufferOwnership : 2; + unsigned m_refCount : 24; - unsigned m_refCountAndFlags; unsigned m_length; }; diff --git a/Source/JavaScriptCore/wtf/text/WTFString.h b/Source/JavaScriptCore/wtf/text/WTFString.h index b593d20..6b1bbfb 100644 --- a/Source/JavaScriptCore/wtf/text/WTFString.h +++ b/Source/JavaScriptCore/wtf/text/WTFString.h @@ -123,7 +123,7 @@ public: bool isNull() const { return !m_impl; } bool isEmpty() const { return !m_impl || !m_impl->length(); } - StringImpl* impl() const { return m_impl.get(); } + ALWAYS_INLINE StringImpl* impl() const { return m_impl.get(); } unsigned length() const { -- cgit v1.1