Diff
Modified: trunk/Source/WebCore/CMakeLists.txt (136333 => 136334)
--- trunk/Source/WebCore/CMakeLists.txt 2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/CMakeLists.txt 2012-12-02 12:03:44 UTC (rev 136334)
@@ -1145,6 +1145,7 @@
dom/DocumentFragment.cpp
dom/DocumentParser.cpp
dom/DocumentOrderedMap.cpp
+ dom/DocumentSharedObjectPool.cpp
dom/DocumentStyleSheetCollection.cpp
dom/DocumentType.cpp
dom/Element.cpp
Modified: trunk/Source/WebCore/ChangeLog (136333 => 136334)
--- trunk/Source/WebCore/ChangeLog 2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/ChangeLog 2012-12-02 12:03:44 UTC (rev 136334)
@@ -1,3 +1,60 @@
+2012-12-02 Andreas Kling <[email protected]>
+
+ Keep ElementAttributeData sharing cache open for a while after document parsing finishes.
+ <http://webkit.org/b/103720>
+
+ Reviewed by Antti Koivisto.
+
+ Allow web pages that generate content dynamically to benefit more from the ElementAttributeData sharing
+ cache by keeping it open for 10 seconds after document parsing finishes. This enables elements constructed
+ from HTML fragments to share attribute data with other identical elements.
+
+ Elements created via Document.createElement are still unsupported since we don't know the list of attributes
+ at the time of construction.
+
+ 401kB progression on Membuster3.
+
+ Document now holds on to a DocumentSharedObjectPool, accessible via Document::sharedObjectPool().
+ It is non-null during parsing and for some time afterwards, and can be used to implement additional
+ caches that are not worth holding on to permanently.
+
+ * CMakeLists.txt:
+ * GNUmakefile.list.am:
+ * Target.pri:
+ * WebCore.gypi:
+ * WebCore.xcodeproj/project.pbxproj:
+ * WebCore.vcproj/WebCore.vcproj:
+
+ Add new class DocumentSharedObjectPool.
+
+ * dom/Document.cpp:
+ (WebCore::Document::Document):
+ (WebCore::Document::setParsing):
+ (WebCore::Document::finishedParsing):
+ (WebCore::Document::sharedObjectPoolClearTimerFired):
+ * dom/Document.h:
+ (WebCore::Document::sharedObjectPool):
+
+ Create DocumentSharedObjectPool when parsing starts, kill it on a 10s timer after parsing finishes.
+
+ * dom/DocumentSharedObjectPool.cpp: Added.
+ (ImmutableElementAttributeDataCacheKey):
+ (WebCore::ImmutableElementAttributeDataCacheKey::ImmutableElementAttributeDataCacheKey):
+ (WebCore::ImmutableElementAttributeDataCacheKey::operator!=):
+ (WebCore::ImmutableElementAttributeDataCacheKey::hash):
+ (ImmutableElementAttributeDataCacheEntry):
+ (WebCore::ImmutableElementAttributeDataCacheEntry::ImmutableElementAttributeDataCacheEntry):
+ (WebCore::DocumentSharedObjectPool::cachedImmutableElementAttributeData):
+ (WebCore::DocumentSharedObjectPool::DocumentSharedObjectPool):
+ (WebCore::DocumentSharedObjectPool::~DocumentSharedObjectPool):
+ * dom/DocumentSharedObjectPool.h: Added.
+ (DocumentSharedObjectPool):
+ (WebCore::DocumentSharedObjectPool::create):
+ * dom/Element.cpp:
+ (WebCore::Element::parserSetAttributes):
+
+ Moved the ElementAttributeData cache to DocumentSharedObjectPool.
+
2012-12-02 John Bauman <[email protected]>
[chromium] Let Pepper Flash use integrated GPU
Modified: trunk/Source/WebCore/GNUmakefile.list.am (136333 => 136334)
--- trunk/Source/WebCore/GNUmakefile.list.am 2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/GNUmakefile.list.am 2012-12-02 12:03:44 UTC (rev 136334)
@@ -2757,6 +2757,8 @@
Source/WebCore/dom/DocumentOrderedMap.h \
Source/WebCore/dom/DocumentParser.cpp \
Source/WebCore/dom/DocumentParser.h \
+ Source/WebCore/dom/DocumentSharedObjectPool.cpp \
+ Source/WebCore/dom/DocumentSharedObjectPool.h \
Source/WebCore/dom/DocumentStyleSheetCollection.cpp \
Source/WebCore/dom/DocumentStyleSheetCollection.h \
Source/WebCore/dom/DocumentTiming.h \
Modified: trunk/Source/WebCore/Target.pri (136333 => 136334)
--- trunk/Source/WebCore/Target.pri 2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/Target.pri 2012-12-02 12:03:44 UTC (rev 136334)
@@ -375,6 +375,7 @@
dom/DocumentMarker.cpp \
dom/DocumentOrderedMap.cpp \
dom/DocumentParser.cpp \
+ dom/DocumentSharedObjectPool.cpp \
dom/DocumentStyleSheetCollection.cpp \
dom/DocumentType.cpp \
dom/DOMCoreException.cpp \
@@ -1556,6 +1557,7 @@
dom/DocumentMarker.h \
dom/DocumentMarkerController.h \
dom/DocumentOrderedMap.h \
+ dom/DocumentSharedObjectPool.h \
dom/DocumentStyleSheetCollection.h \
dom/DocumentType.h \
dom/DOMError.h \
Modified: trunk/Source/WebCore/WebCore.gypi (136333 => 136334)
--- trunk/Source/WebCore/WebCore.gypi 2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/WebCore.gypi 2012-12-02 12:03:44 UTC (rev 136334)
@@ -659,6 +659,7 @@
'dom/DocumentMarkerController.h',
'dom/DocumentOrderedMap.h',
'dom/DocumentParser.h',
+ 'dom/DocumentSharedObjectPool.h',
'dom/DocumentStyleSheetCollection.h',
'dom/DocumentTiming.h',
'dom/DocumentType.h',
@@ -3806,6 +3807,7 @@
'dom/DocumentMarker.cpp',
'dom/DocumentOrderedMap.cpp',
'dom/DocumentParser.cpp',
+ 'dom/DocumentSharedObjectPool.cpp',
'dom/DocumentStyleSheetCollection.cpp',
'dom/DocumentType.cpp',
'dom/ElementShadow.cpp',
Modified: trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj (136333 => 136334)
--- trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj 2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj 2012-12-02 12:03:44 UTC (rev 136334)
@@ -50674,6 +50674,14 @@
>
</File>
<File
+ RelativePath="..\dom\DocumentSharedObjectPool.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\dom\DocumentSharedObjectPool.h"
+ >
+ </File>
+ <File
RelativePath="..\dom\DocumentStyleSheetCollection.cpp"
>
</File>
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (136333 => 136334)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2012-12-02 12:03:44 UTC (rev 136334)
@@ -4626,6 +4626,8 @@
AD03AAFA1468455300A39B5B /* CSSValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD03AAF81468453900A39B5B /* CSSValue.cpp */; };
AD4495F3141FC08900541EDF /* EventListenerMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD4495F1141FC08900541EDF /* EventListenerMap.cpp */; };
AD4495F4141FC08900541EDF /* EventListenerMap.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4495F2141FC08900541EDF /* EventListenerMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ AD6E71AC1668899D00320C13 /* DocumentSharedObjectPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD6E71AA1668899D00320C13 /* DocumentSharedObjectPool.cpp */; };
+ AD6E71AD1668899D00320C13 /* DocumentSharedObjectPool.h in Headers */ = {isa = PBXBuildFile; fileRef = AD6E71AB1668899D00320C13 /* DocumentSharedObjectPool.h */; };
ADDF1AD71257CD9A0003A759 /* RenderSVGPath.h in Headers */ = {isa = PBXBuildFile; fileRef = ADDF1AD51257CD9A0003A759 /* RenderSVGPath.h */; };
B10B6980140C174000BC1C26 /* WebVTTToken.h in Headers */ = {isa = PBXBuildFile; fileRef = B10B697D140C174000BC1C26 /* WebVTTToken.h */; };
B10B6981140C174000BC1C26 /* WebVTTTokenizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B10B697E140C174000BC1C26 /* WebVTTTokenizer.cpp */; };
@@ -11845,6 +11847,8 @@
AD03AAF81468453900A39B5B /* CSSValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSValue.cpp; sourceTree = "<group>"; };
AD4495F1141FC08900541EDF /* EventListenerMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventListenerMap.cpp; sourceTree = "<group>"; };
AD4495F2141FC08900541EDF /* EventListenerMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventListenerMap.h; sourceTree = "<group>"; };
+ AD6E71AA1668899D00320C13 /* DocumentSharedObjectPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentSharedObjectPool.cpp; sourceTree = "<group>"; };
+ AD6E71AB1668899D00320C13 /* DocumentSharedObjectPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentSharedObjectPool.h; sourceTree = "<group>"; };
ADDF1AD41257CD9A0003A759 /* RenderSVGPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGPath.cpp; sourceTree = "<group>"; };
ADDF1AD51257CD9A0003A759 /* RenderSVGPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGPath.h; sourceTree = "<group>"; };
B10B697D140C174000BC1C26 /* WebVTTToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebVTTToken.h; sourceTree = "<group>"; };
@@ -22194,6 +22198,8 @@
93EEC1F709C2877700C515D1 /* WheelEvent.idl */,
4123E568127B3041000FEEA7 /* WindowEventContext.cpp */,
4123E567127B3041000FEEA7 /* WindowEventContext.h */,
+ AD6E71AA1668899D00320C13 /* DocumentSharedObjectPool.cpp */,
+ AD6E71AB1668899D00320C13 /* DocumentSharedObjectPool.h */,
);
path = dom;
sourceTree = "<group>";
@@ -25851,6 +25857,7 @@
53EF766B16530A61004CBE49 /* SettingsMacros.h in Headers */,
447958041643B49A001E0A7F /* ParsedContentType.h in Headers */,
FB2C15C3165D649D0039C9F8 /* CachedSVGDocumentReference.h in Headers */,
+ AD6E71AD1668899D00320C13 /* DocumentSharedObjectPool.h in Headers */,
31741AAD16636609008A5B7E /* SimulatedClickOptions.h in Headers */,
15B8B7C91652C5220036EF55 /* JSWebKitCSSMixFunctionValue.h in Headers */,
93F72AF31666EDFC002A02BD /* LayerPool.h in Headers */,
@@ -28954,6 +28961,7 @@
570B78BF1650CE81001DBE1B /* SelectRuleFeatureSet.cpp in Sources */,
1E50084816516AD800B7E098 /* RenderThemeMacShared.mm in Sources */,
CD7E05221651C28200C1201F /* WebCoreAVFResourceLoader.mm in Sources */,
+ AD6E71AC1668899D00320C13 /* DocumentSharedObjectPool.cpp in Sources */,
447958051643B4B2001E0A7F /* ParsedContentType.cpp in Sources */,
15B8B7C81652C5220036EF55 /* JSWebKitCSSMixFunctionValue.cpp in Sources */,
86BA766E166427A8005BE5D1 /* FrameLoadRequest.cpp in Sources */,
Modified: trunk/Source/WebCore/dom/DOMAllInOne.cpp (136333 => 136334)
--- trunk/Source/WebCore/dom/DOMAllInOne.cpp 2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/dom/DOMAllInOne.cpp 2012-12-02 12:03:44 UTC (rev 136334)
@@ -66,6 +66,7 @@
#include "DocumentMarkerController.cpp"
#include "DocumentOrderedMap.cpp"
#include "DocumentParser.cpp"
+#include "DocumentSharedObjectPool.cpp"
#include "DocumentType.cpp"
#include "Element.cpp"
#include "ElementAttributeData.cpp"
Modified: trunk/Source/WebCore/dom/Document.cpp (136333 => 136334)
--- trunk/Source/WebCore/dom/Document.cpp 2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/dom/Document.cpp 2012-12-02 12:03:44 UTC (rev 136334)
@@ -55,6 +55,7 @@
#include "DocumentFragment.h"
#include "DocumentLoader.h"
#include "DocumentMarkerController.h"
+#include "DocumentSharedObjectPool.h"
#include "DocumentStyleSheetCollection.h"
#include "DocumentType.h"
#include "Editor.h"
@@ -500,6 +501,7 @@
, m_scheduledTasksAreSuspended(false)
, m_visualUpdatesAllowed(true)
, m_visualUpdatesSuppressionTimer(this, &Document::visualUpdatesSuppressionTimerFired)
+ , m_sharedObjectPoolClearTimer(this, &Document::sharedObjectPoolClearTimerFired)
#ifndef NDEBUG
, m_didDispatchViewportPropertiesChanged(false)
#endif
@@ -2491,6 +2493,10 @@
void Document::setParsing(bool b)
{
m_bParsing = b;
+
+ if (m_bParsing && !m_sharedObjectPool)
+ m_sharedObjectPool = DocumentSharedObjectPool::create();
+
if (!m_bParsing && view())
view()->scheduleRelayout();
@@ -4415,11 +4421,19 @@
InspectorInstrumentation::domContentLoadedEventFired(f.get());
}
- // The ElementAttributeData sharing cache is only used during parsing since
- // that's when the majority of immutable attribute data will be created.
- m_immutableAttributeDataCache.clear();
+ // Schedule dropping of the DocumentSharedObjectPool. We keep it alive for a while after parsing finishes
+ // so that dynamically inserted content can also benefit from sharing optimizations.
+ // Note that we don't refresh the timer on pool access since that could lead to huge caches being kept
+ // alive indefinitely by something innocuous like JS setting .innerHTML repeatedly on a timer.
+ static const int timeToKeepSharedObjectPoolAliveAfterParsingFinishedInSeconds = 10;
+ m_sharedObjectPoolClearTimer.startOneShot(timeToKeepSharedObjectPoolAliveAfterParsingFinishedInSeconds);
}
+void Document::sharedObjectPoolClearTimerFired(Timer<Document>*)
+{
+ m_sharedObjectPool.clear();
+}
+
PassRefPtr<XPathExpression> Document::createExpression(const String& _expression_,
XPathNSResolver* resolver,
ExceptionCode& ec)
@@ -5860,65 +5874,6 @@
info.addMember(m_listsInvalidatedAtDocument);
}
-class ImmutableAttributeDataCacheKey {
-public:
- ImmutableAttributeDataCacheKey(const Attribute* attributes, unsigned attributeCount)
- : m_attributes(attributes)
- , m_attributeCount(attributeCount)
- { }
-
- bool operator!=(const ImmutableAttributeDataCacheKey& other) const
- {
- if (m_attributeCount != other.m_attributeCount)
- return true;
- return memcmp(m_attributes, other.m_attributes, sizeof(Attribute) * m_attributeCount);
- }
-
- unsigned hash() const
- {
- return StringHasher::hashMemory(m_attributes, m_attributeCount * sizeof(Attribute));
- }
-
-private:
- const Attribute* m_attributes;
- unsigned m_attributeCount;
-};
-
-struct ImmutableAttributeDataCacheEntry {
- ImmutableAttributeDataCacheEntry(const ImmutableAttributeDataCacheKey& k, PassRefPtr<ElementAttributeData> v)
- : key(k)
- , value(v)
- { }
-
- ImmutableAttributeDataCacheKey key;
- RefPtr<ElementAttributeData> value;
-};
-
-PassRefPtr<ElementAttributeData> Document::cachedImmutableAttributeData(const Vector<Attribute>& attributes)
-{
- ASSERT(!attributes.isEmpty());
-
- ImmutableAttributeDataCacheKey cacheKey(attributes.data(), attributes.size());
- unsigned cacheHash = cacheKey.hash();
-
- ImmutableAttributeDataCache::iterator cacheIterator = m_immutableAttributeDataCache.add(cacheHash, nullptr).iterator;
- if (cacheIterator->value && cacheIterator->value->key != cacheKey)
- cacheHash = 0;
-
- RefPtr<ElementAttributeData> attributeData;
- if (cacheHash && cacheIterator->value)
- attributeData = cacheIterator->value->value;
- else
- attributeData = ElementAttributeData::createImmutable(attributes);
-
- if (!cacheHash || cacheIterator->value)
- return attributeData.release();
-
- cacheIterator->value = adoptPtr(new ImmutableAttributeDataCacheEntry(ImmutableAttributeDataCacheKey(attributeData->immutableAttributeArray(), attributeData->length()), attributeData));
-
- return attributeData.release();
-}
-
bool Document::haveStylesheetsLoaded() const
{
return !m_styleSheetCollection->hasPendingSheets() || m_ignorePendingStylesheets;
Modified: trunk/Source/WebCore/dom/Document.h (136333 => 136334)
--- trunk/Source/WebCore/dom/Document.h 2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/dom/Document.h 2012-12-02 12:03:44 UTC (rev 136334)
@@ -77,11 +77,11 @@
class DocumentLoader;
class DocumentMarkerController;
class DocumentParser;
+class DocumentSharedObjectPool;
class DocumentStyleSheetCollection;
class DocumentType;
class DocumentWeakReference;
class Element;
-class ElementAttributeData;
class EntityReference;
class Event;
class EventListener;
@@ -206,9 +206,6 @@
};
const int numNodeListInvalidationTypes = InvalidateOnAnyAttrChange + 1;
-struct ImmutableAttributeDataCacheEntry;
-typedef HashMap<unsigned, OwnPtr<ImmutableAttributeDataCacheEntry>, AlreadyHashed> ImmutableAttributeDataCache;
-
class Document : public ContainerNode, public TreeScope, public ScriptExecutionContext {
public:
static PassRefPtr<Document> create(Frame* frame, const KURL& url)
@@ -1153,7 +1150,7 @@
virtual void reportMemoryUsage(MemoryObjectInfo*) const OVERRIDE;
- PassRefPtr<ElementAttributeData> cachedImmutableAttributeData(const Vector<Attribute>&);
+ DocumentSharedObjectPool* sharedObjectPool() { return m_sharedObjectPool.get(); }
void didRemoveAllPendingStylesheet();
void setNeedsNotifyRemoveAllPendingStylesheet() { m_needsNotifyRemoveAllPendingStylesheet = true; }
@@ -1515,8 +1512,11 @@
RefPtr<DOMSecurityPolicy> m_domSecurityPolicy;
#endif
- ImmutableAttributeDataCache m_immutableAttributeDataCache;
+ void sharedObjectPoolClearTimerFired(Timer<Document>*);
+ Timer<Document> m_sharedObjectPoolClearTimer;
+ OwnPtr<DocumentSharedObjectPool> m_sharedObjectPool;
+
#ifndef NDEBUG
bool m_didDispatchViewportPropertiesChanged;
#endif
Added: trunk/Source/WebCore/dom/DocumentSharedObjectPool.cpp (0 => 136334)
--- trunk/Source/WebCore/dom/DocumentSharedObjectPool.cpp (rev 0)
+++ trunk/Source/WebCore/dom/DocumentSharedObjectPool.cpp 2012-12-02 12:03:44 UTC (rev 136334)
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2012 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 COMPUTER, 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 COMPUTER, 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"
+#include "DocumentSharedObjectPool.h"
+
+#include "Attribute.h"
+#include "ElementAttributeData.h"
+
+namespace WebCore {
+
+class ImmutableElementAttributeDataCacheKey {
+public:
+ ImmutableElementAttributeDataCacheKey(const Attribute* attributes, unsigned attributeCount)
+ : m_attributes(attributes)
+ , m_attributeCount(attributeCount)
+ { }
+
+ bool operator!=(const ImmutableElementAttributeDataCacheKey& other) const
+ {
+ if (m_attributeCount != other.m_attributeCount)
+ return true;
+ return memcmp(m_attributes, other.m_attributes, sizeof(Attribute) * m_attributeCount);
+ }
+
+ unsigned hash() const
+ {
+ return StringHasher::hashMemory(m_attributes, m_attributeCount * sizeof(Attribute));
+ }
+
+private:
+ const Attribute* m_attributes;
+ unsigned m_attributeCount;
+};
+
+class ImmutableElementAttributeDataCacheEntry {
+public:
+ ImmutableElementAttributeDataCacheEntry(const ImmutableElementAttributeDataCacheKey& k, PassRefPtr<ElementAttributeData> v)
+ : key(k)
+ , value(v)
+ { }
+
+ ImmutableElementAttributeDataCacheKey key;
+ RefPtr<ElementAttributeData> value;
+};
+
+PassRefPtr<ElementAttributeData> DocumentSharedObjectPool::cachedImmutableElementAttributeData(const Vector<Attribute>& attributes)
+{
+ ASSERT(!attributes.isEmpty());
+
+ ImmutableElementAttributeDataCacheKey cacheKey(attributes.data(), attributes.size());
+ unsigned cacheHash = cacheKey.hash();
+
+ ImmutableElementAttributeDataCache::iterator cacheIterator = m_immutableElementAttributeDataCache.add(cacheHash, nullptr).iterator;
+ if (cacheIterator->value && cacheIterator->value->key != cacheKey)
+ cacheHash = 0;
+
+ RefPtr<ElementAttributeData> attributeData;
+ if (cacheHash && cacheIterator->value)
+ attributeData = cacheIterator->value->value;
+ else
+ attributeData = ElementAttributeData::createImmutable(attributes);
+
+ if (!cacheHash || cacheIterator->value)
+ return attributeData.release();
+
+ cacheIterator->value = adoptPtr(new ImmutableElementAttributeDataCacheEntry(ImmutableElementAttributeDataCacheKey(attributeData->immutableAttributeArray(), attributeData->length()), attributeData));
+
+ return attributeData.release();
+}
+
+DocumentSharedObjectPool::DocumentSharedObjectPool()
+{
+}
+
+DocumentSharedObjectPool::~DocumentSharedObjectPool()
+{
+}
+
+}
Added: trunk/Source/WebCore/dom/DocumentSharedObjectPool.h (0 => 136334)
--- trunk/Source/WebCore/dom/DocumentSharedObjectPool.h (rev 0)
+++ trunk/Source/WebCore/dom/DocumentSharedObjectPool.h 2012-12-02 12:03:44 UTC (rev 136334)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2012 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 COMPUTER, 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 COMPUTER, 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.
+ *
+ */
+
+#ifndef DocumentSharedObjectPool_h
+#define DocumentSharedObjectPool_h
+
+#include <wtf/HashMap.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+class Attribute;
+class ElementAttributeData;
+class ImmutableElementAttributeDataCacheEntry;
+
+class DocumentSharedObjectPool {
+public:
+ static PassOwnPtr<DocumentSharedObjectPool> create() { return adoptPtr(new DocumentSharedObjectPool); }
+ ~DocumentSharedObjectPool();
+
+ PassRefPtr<ElementAttributeData> cachedImmutableElementAttributeData(const Vector<Attribute>&);
+
+private:
+ DocumentSharedObjectPool();
+
+ typedef HashMap<unsigned, OwnPtr<ImmutableElementAttributeDataCacheEntry>, AlreadyHashed> ImmutableElementAttributeDataCache;
+ ImmutableElementAttributeDataCache m_immutableElementAttributeDataCache;
+};
+
+}
+
+#endif
Modified: trunk/Source/WebCore/dom/Element.cpp (136333 => 136334)
--- trunk/Source/WebCore/dom/Element.cpp 2012-12-02 11:56:17 UTC (rev 136333)
+++ trunk/Source/WebCore/dom/Element.cpp 2012-12-02 12:03:44 UTC (rev 136334)
@@ -37,6 +37,7 @@
#include "DatasetDOMStringMap.h"
#include "Document.h"
#include "DocumentFragment.h"
+#include "DocumentSharedObjectPool.h"
#include "ElementRareData.h"
#include "ExceptionCode.h"
#include "FlowThreadController.h"
@@ -976,12 +977,10 @@
}
}
- // When the document is in parsing state, we cache immutable ElementAttributeData objects with the
- // input attribute vector as key. (This cache is held by Document.)
- if (!document() || !document()->parsing())
- m_attributeData = ElementAttributeData::createImmutable(filteredAttributes);
+ if (document() && document()->sharedObjectPool())
+ m_attributeData = document()->sharedObjectPool()->cachedImmutableElementAttributeData(filteredAttributes);
else
- m_attributeData = document()->cachedImmutableAttributeData(filteredAttributes);
+ m_attributeData = ElementAttributeData::createImmutable(filteredAttributes);
// Iterate over the set of attributes we already have on the stack in case
// attributeChanged mutates m_attributeData.