Source/WebCore:
authorakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 11 Jan 2016 12:23:57 +0000 (12:23 +0000)
committerakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 11 Jan 2016 12:23:57 +0000 (12:23 +0000)
CSSValuePool should use nonfragmented storage for eternal caches.
<https://webkit.org/b/152960>

Reviewed by Antti Koivisto.

Store all of the common cached CSS value objects in contiguous arrays
instead of lazily allocating them on the heap.

This reduces heap fragmentation (win) and removes indirection (win)

* css/CSSInheritedValue.h:
* css/CSSInitialValue.h:
* css/CSSPrimitiveValue.h:
* css/CSSRevertValue.h:
* css/CSSUnsetValue.h:
* css/CSSValuePool.cpp:
(WebCore::CSSValuePool::CSSValuePool):
(WebCore::CSSValuePool::createIdentifierValue):
(WebCore::CSSValuePool::createColorValue):
(WebCore::CSSValuePool::createValue):
(WebCore::CSSValuePool::drain): Deleted.
* css/CSSValuePool.h:
(WebCore::CSSValuePool::createInheritedValue):
(WebCore::CSSValuePool::createImplicitInitialValue):
(WebCore::CSSValuePool::createExplicitInitialValue):
(WebCore::CSSValuePool::createUnsetValue):
(WebCore::CSSValuePool::createRevertValue):

Source/WTF:
NeverDestroyed should relax adoption requirements on all RefCountedBase subclasses.
<https://webkit.org/b/152960>

Reviewed by Antti Koivisto.

Instead of relaxing on subclasses of RefCounted<T>, relax on subclasses of RefCountedBase.
This allows e.g NeverDestroyed<CSSPrimitiveValue> to relax its pointee despite the class
hierarchy starting with RefCounted<CSSValue> (not RefCounted<CSSPrimitiveValue>.)

* wtf/NeverDestroyed.h:

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

Source/WTF/ChangeLog
Source/WTF/wtf/NeverDestroyed.h
Source/WebCore/ChangeLog
Source/WebCore/css/CSSInheritedValue.h
Source/WebCore/css/CSSInitialValue.h
Source/WebCore/css/CSSPrimitiveValue.h
Source/WebCore/css/CSSRevertValue.h
Source/WebCore/css/CSSUnsetValue.h
Source/WebCore/css/CSSValuePool.cpp
Source/WebCore/css/CSSValuePool.h

index 9d91083..400c4ef 100644 (file)
@@ -1,3 +1,16 @@
+2016-01-11  Andreas Kling  <akling@apple.com>
+
+        NeverDestroyed should relax adoption requirements on all RefCountedBase subclasses.
+        <https://webkit.org/b/152960>
+
+        Reviewed by Antti Koivisto.
+
+        Instead of relaxing on subclasses of RefCounted<T>, relax on subclasses of RefCountedBase.
+        This allows e.g NeverDestroyed<CSSPrimitiveValue> to relax its pointee despite the class
+        hierarchy starting with RefCounted<CSSValue> (not RefCounted<CSSPrimitiveValue>.)
+
+        * wtf/NeverDestroyed.h:
+
 2016-01-10  Saam barati  <sbarati@apple.com>
 
         Implement a sampling profiler
index 1e36a86..b824634 100644 (file)
@@ -65,7 +65,7 @@ private:
     // and hand out chunks of it to NeverDestroyed instead, to reduce fragmentation.
     typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type m_storage;
 
-    template <typename PtrType, bool ShouldRelax = std::is_base_of<RefCounted<PtrType>, PtrType>::value> struct MaybeRelax {
+    template <typename PtrType, bool ShouldRelax = std::is_base_of<RefCountedBase, PtrType>::value> struct MaybeRelax {
         explicit MaybeRelax(PtrType*) { }
     };
     template <typename PtrType> struct MaybeRelax<PtrType, true> {
@@ -110,7 +110,7 @@ private:
     // and hand out chunks of it to NeverDestroyed instead, to reduce fragmentation.
     typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type m_storage;
 
-    template <typename PtrType, bool ShouldRelax = std::is_base_of<RefCounted<PtrType>, PtrType>::value> struct MaybeRelax {
+    template <typename PtrType, bool ShouldRelax = std::is_base_of<RefCountedBase, PtrType>::value> struct MaybeRelax {
         explicit MaybeRelax(PtrType*) { }
     };
     template <typename PtrType> struct MaybeRelax<PtrType, true> {
index 10d2cc8..297e6ab 100644 (file)
@@ -1,3 +1,33 @@
+2016-01-11  Andreas Kling  <akling@apple.com>
+
+        CSSValuePool should use nonfragmented storage for eternal caches.
+        <https://webkit.org/b/152960>
+
+        Reviewed by Antti Koivisto.
+
+        Store all of the common cached CSS value objects in contiguous arrays
+        instead of lazily allocating them on the heap.
+
+        This reduces heap fragmentation (win) and removes indirection (win)
+
+        * css/CSSInheritedValue.h:
+        * css/CSSInitialValue.h:
+        * css/CSSPrimitiveValue.h:
+        * css/CSSRevertValue.h:
+        * css/CSSUnsetValue.h:
+        * css/CSSValuePool.cpp:
+        (WebCore::CSSValuePool::CSSValuePool):
+        (WebCore::CSSValuePool::createIdentifierValue):
+        (WebCore::CSSValuePool::createColorValue):
+        (WebCore::CSSValuePool::createValue):
+        (WebCore::CSSValuePool::drain): Deleted.
+        * css/CSSValuePool.h:
+        (WebCore::CSSValuePool::createInheritedValue):
+        (WebCore::CSSValuePool::createImplicitInitialValue):
+        (WebCore::CSSValuePool::createExplicitInitialValue):
+        (WebCore::CSSValuePool::createUnsetValue):
+        (WebCore::CSSValuePool::createRevertValue):
+
 2016-01-11  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] Cleanup RenderThemeGtk
index 8a63765..8d43384 100644 (file)
@@ -22,7 +22,7 @@
 #define CSSInheritedValue_h
 
 #include "CSSValue.h"
-#include <wtf/PassRefPtr.h>
+#include <wtf/NeverDestroyed.h>
 
 namespace WebCore {
 
@@ -38,6 +38,8 @@ public:
     bool equals(const CSSInheritedValue&) const { return true; }
 
 private:
+    friend class LazyNeverDestroyed<CSSInheritedValue>;
+
     CSSInheritedValue()
         : CSSValue(InheritedClass)
     {
index a711adf..1b9c4e8 100644 (file)
@@ -22,7 +22,7 @@
 #define CSSInitialValue_h
 
 #include "CSSValue.h"
-#include <wtf/PassRefPtr.h>
+#include <wtf/NeverDestroyed.h>
 
 namespace WebCore {
 
@@ -44,6 +44,8 @@ public:
     bool equals(const CSSInitialValue&) const { return true; }
 
 private:
+    friend class LazyNeverDestroyed<CSSInitialValue>;
+
     CSSInitialValue(bool implicit)
         : CSSValue(InitialClass)
         , m_isImplicit(implicit)
index 9a42cbe..14a040e 100644 (file)
@@ -30,7 +30,7 @@
 #include <utility>
 #include <wtf/Forward.h>
 #include <wtf/MathExtras.h>
-#include <wtf/PassRefPtr.h>
+#include <wtf/NeverDestroyed.h>
 
 namespace WebCore {
 
@@ -383,6 +383,9 @@ public:
 
     static double computeNonCalcLengthDouble(const CSSToLengthConversionData&, unsigned short primitiveType, double value);
 private:
+    friend class CSSValuePool;
+    friend class LazyNeverDestroyed<CSSPrimitiveValue>;
+
     CSSPrimitiveValue(CSSValueID);
     CSSPrimitiveValue(CSSPropertyID);
     // FIXME: int vs. unsigned overloading is too subtle to distinguish the color and operator cases.
index 22235a4..72fe723 100644 (file)
@@ -27,7 +27,7 @@
 #define CSSRevertValue_h
 
 #include "CSSValue.h"
-#include <wtf/PassRefPtr.h>
+#include <wtf/NeverDestroyed.h>
 
 namespace WebCore {
 
@@ -43,6 +43,8 @@ public:
     bool equals(const CSSRevertValue&) const { return true; }
 
 private:
+    friend class LazyNeverDestroyed<CSSRevertValue>;
+
     CSSRevertValue()
         : CSSValue(RevertClass)
     {
index 0aa6c22..ffa86b2 100644 (file)
@@ -27,7 +27,7 @@
 #define CSSUnsetValue_h
 
 #include "CSSValue.h"
-#include <wtf/PassRefPtr.h>
+#include <wtf/NeverDestroyed.h>
 
 namespace WebCore {
 
@@ -43,6 +43,8 @@ public:
     bool equals(const CSSUnsetValue&) const { return true; }
 
 private:
+    friend class LazyNeverDestroyed<CSSUnsetValue>;
+
     CSSUnsetValue()
         : CSSValue(UnsetClass)
     {
index 0d62472..e767377 100644 (file)
@@ -41,26 +41,31 @@ CSSValuePool& CSSValuePool::singleton()
 }
 
 CSSValuePool::CSSValuePool()
-    : m_inheritedValue(CSSInheritedValue::create())
-    , m_implicitInitialValue(CSSInitialValue::createImplicit())
-    , m_explicitInitialValue(CSSInitialValue::createExplicit())
-    , m_unsetValue(CSSUnsetValue::create())
-    , m_revertValue(CSSRevertValue::create())
-    , m_colorTransparent(CSSPrimitiveValue::createColor(Color::transparent))
-    , m_colorWhite(CSSPrimitiveValue::createColor(Color::white))
-    , m_colorBlack(CSSPrimitiveValue::createColor(Color::black))
 {
+    m_inheritedValue.construct();
+    m_implicitInitialValue.construct(true);
+    m_explicitInitialValue.construct(false);
+    m_unsetValue.construct();
+    m_revertValue.construct();
+
+    m_transparentColor.construct(Color::transparent);
+    m_whiteColor.construct(Color::white);
+    m_blackColor.construct(Color::black);
+
+    for (unsigned i = 0; i < numCSSValueKeywords; ++i)
+        m_identifierValues[i].construct(static_cast<CSSValueID>(i));
+
+    for (unsigned i = 0; i < (maximumCacheableIntegerValue + 1); ++i) {
+        m_pixelValues[i].construct(i, CSSPrimitiveValue::CSS_PX);
+        m_percentValues[i].construct(i, CSSPrimitiveValue::CSS_PERCENTAGE);
+        m_numberValues[i].construct(i, CSSPrimitiveValue::CSS_NUMBER);
+    }
 }
 
 Ref<CSSPrimitiveValue> CSSValuePool::createIdentifierValue(CSSValueID ident)
 {
-    if (!ident)
-        return CSSPrimitiveValue::createIdentifier(ident);
-
-    RELEASE_ASSERT(ident > 0 && ident < numCSSValueKeywords);
-    if (!m_identifierValueCache[ident])
-        m_identifierValueCache[ident] = CSSPrimitiveValue::createIdentifier(ident);
-    return *m_identifierValueCache[ident];
+    RELEASE_ASSERT(ident >= 0 && ident < numCSSValueKeywords);
+    return m_identifierValues[ident].get();
 }
 
 Ref<CSSPrimitiveValue> CSSValuePool::createIdentifierValue(CSSPropertyID ident)
@@ -72,12 +77,12 @@ Ref<CSSPrimitiveValue> CSSValuePool::createColorValue(unsigned rgbValue)
 {
     // These are the empty and deleted values of the hash table.
     if (rgbValue == Color::transparent)
-        return m_colorTransparent.copyRef();
+        return m_transparentColor.get();
     if (rgbValue == Color::white)
-        return m_colorWhite.copyRef();
+        return m_whiteColor.get();
     // Just because it is common.
     if (rgbValue == Color::black)
-        return m_colorBlack.copyRef();
+        return m_blackColor.get();
 
     // Remove one entry at random if the cache grows too large.
     const int maximumColorCacheSize = 512;
@@ -101,24 +106,16 @@ Ref<CSSPrimitiveValue> CSSValuePool::createValue(double value, CSSPrimitiveValue
     if (value != intValue)
         return CSSPrimitiveValue::create(value, type);
 
-    RefPtr<CSSPrimitiveValue>* cache;
     switch (type) {
     case CSSPrimitiveValue::CSS_PX:
-        cache = m_pixelValueCache;
-        break;
+        return m_pixelValues[intValue].get();
     case CSSPrimitiveValue::CSS_PERCENTAGE:
-        cache = m_percentValueCache;
-        break;
+        return m_percentValues[intValue].get();
     case CSSPrimitiveValue::CSS_NUMBER:
-        cache = m_numberValueCache;
-        break;
+        return m_numberValues[intValue].get();
     default:
         return CSSPrimitiveValue::create(value, type);
     }
-
-    if (!cache[intValue])
-        cache[intValue] = CSSPrimitiveValue::create(value, type);
-    return *cache[intValue];
 }
 
 Ref<CSSPrimitiveValue> CSSValuePool::createFontFamilyValue(const String& familyName, FromSystemFontID fromSystemFontID)
@@ -153,15 +150,6 @@ void CSSValuePool::drain()
     m_colorValueCache.clear();
     m_fontFaceValueCache.clear();
     m_fontFamilyValueCache.clear();
-
-    for (int i = 0; i < numCSSValueKeywords; ++i)
-        m_identifierValueCache[i] = nullptr;
-
-    for (int i = 0; i < maximumCacheableIntegerValue; ++i) {
-        m_pixelValueCache[i] = nullptr;
-        m_percentValueCache[i] = nullptr;
-        m_numberValueCache[i] = nullptr;
-    }
 }
 
 }
index a16ec46..d1cb424 100644 (file)
@@ -53,11 +53,11 @@ public:
 
     PassRefPtr<CSSValueList> createFontFaceValue(const AtomicString&);
     Ref<CSSPrimitiveValue> createFontFamilyValue(const String&, FromSystemFontID = FromSystemFontID::No);
-    Ref<CSSInheritedValue> createInheritedValue() { return m_inheritedValue.copyRef(); }
-    Ref<CSSInitialValue> createImplicitInitialValue() { return m_implicitInitialValue.copyRef(); }
-    Ref<CSSInitialValue> createExplicitInitialValue() { return m_explicitInitialValue.copyRef(); }
-    Ref<CSSUnsetValue> createUnsetValue() { return m_unsetValue.copyRef(); }
-    Ref<CSSRevertValue> createRevertValue() { return m_revertValue.copyRef(); }
+    Ref<CSSInheritedValue> createInheritedValue() { return m_inheritedValue.get(); }
+    Ref<CSSInitialValue> createImplicitInitialValue() { return m_implicitInitialValue.get(); }
+    Ref<CSSInitialValue> createExplicitInitialValue() { return m_explicitInitialValue.get(); }
+    Ref<CSSUnsetValue> createUnsetValue() { return m_unsetValue.get(); }
+    Ref<CSSRevertValue> createRevertValue() { return m_revertValue.get(); }
     Ref<CSSPrimitiveValue> createIdentifierValue(CSSValueID identifier);
     Ref<CSSPrimitiveValue> createIdentifierValue(CSSPropertyID identifier);
     Ref<CSSPrimitiveValue> createColorValue(unsigned rgbValue);
@@ -72,25 +72,8 @@ public:
 private:
     CSSValuePool();
 
-    Ref<CSSInheritedValue> m_inheritedValue;
-    Ref<CSSInitialValue> m_implicitInitialValue;
-    Ref<CSSInitialValue> m_explicitInitialValue;
-    Ref<CSSUnsetValue> m_unsetValue;
-    Ref<CSSRevertValue> m_revertValue;
-
-    RefPtr<CSSPrimitiveValue> m_identifierValueCache[numCSSValueKeywords];
-
     typedef HashMap<unsigned, RefPtr<CSSPrimitiveValue>> ColorValueCache;
     ColorValueCache m_colorValueCache;
-    Ref<CSSPrimitiveValue> m_colorTransparent;
-    Ref<CSSPrimitiveValue> m_colorWhite;
-    Ref<CSSPrimitiveValue> m_colorBlack;
-
-    static const int maximumCacheableIntegerValue = 255;
-
-    RefPtr<CSSPrimitiveValue> m_pixelValueCache[maximumCacheableIntegerValue + 1];
-    RefPtr<CSSPrimitiveValue> m_percentValueCache[maximumCacheableIntegerValue + 1];
-    RefPtr<CSSPrimitiveValue> m_numberValueCache[maximumCacheableIntegerValue + 1];
 
     typedef HashMap<AtomicString, RefPtr<CSSValueList>> FontFaceValueCache;
     FontFaceValueCache m_fontFaceValueCache;
@@ -99,6 +82,23 @@ private:
     FontFamilyValueCache m_fontFamilyValueCache;
 
     friend class WTF::NeverDestroyed<CSSValuePool>;
+
+    LazyNeverDestroyed<CSSInheritedValue> m_inheritedValue;
+    LazyNeverDestroyed<CSSInitialValue> m_implicitInitialValue;
+    LazyNeverDestroyed<CSSInitialValue> m_explicitInitialValue;
+    LazyNeverDestroyed<CSSUnsetValue> m_unsetValue;
+    LazyNeverDestroyed<CSSRevertValue> m_revertValue;
+
+    LazyNeverDestroyed<CSSPrimitiveValue> m_transparentColor;
+    LazyNeverDestroyed<CSSPrimitiveValue> m_whiteColor;
+    LazyNeverDestroyed<CSSPrimitiveValue> m_blackColor;
+
+    static const int maximumCacheableIntegerValue = 255;
+
+    LazyNeverDestroyed<CSSPrimitiveValue> m_pixelValues[maximumCacheableIntegerValue + 1];
+    LazyNeverDestroyed<CSSPrimitiveValue> m_percentValues[maximumCacheableIntegerValue + 1];
+    LazyNeverDestroyed<CSSPrimitiveValue> m_numberValues[maximumCacheableIntegerValue + 1];
+    LazyNeverDestroyed<CSSPrimitiveValue> m_identifierValues[numCSSValueKeywords];
 };
 
 }