Devirtualize CSSValue.
authorandreas.kling@nokia.com <andreas.kling@nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 8 Nov 2011 18:27:07 +0000 (18:27 +0000)
committerandreas.kling@nokia.com <andreas.kling@nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 8 Nov 2011 18:27:07 +0000 (18:27 +0000)
<http://webkit.org/b/71666>

Reviewed by Antti Koivisto.

Make the CSSValue destructor non-virtual (along with all the subclasses.)
This removes the vtables, and the pointers thereto in each value instance,
shrinking each object by one CPU word (4 or 8 bytes.)

We use the same trick as CSSRule to implement destruction; providing our
own deref() instead of RefCounted's, and performing a statically typed
delete in a destroy() method called when the ref count reaches 0.

Also made all the empty subclass destructors inline.

* css/CSSAspectRatioValue.cpp:
* css/CSSAspectRatioValue.h:
(WebCore::CSSAspectRatioValue::~CSSAspectRatioValue):
* css/CSSBorderImageSliceValue.cpp:
* css/CSSBorderImageSliceValue.h:
(WebCore::CSSBorderImageSliceValue::~CSSBorderImageSliceValue):
* css/CSSBorderImageValue.cpp:
* css/CSSBorderImageValue.h:
(WebCore::CSSBorderImageValue::~CSSBorderImageValue):
* css/CSSCanvasValue.h:
* css/CSSCrossfadeValue.cpp:
* css/CSSCrossfadeValue.h:
(WebCore::CSSCrossfadeValue::~CSSCrossfadeValue):
* css/CSSCursorImageValue.h:
* css/CSSFlexValue.cpp:
* css/CSSFlexValue.h:
(WebCore::CSSFlexValue::~CSSFlexValue):
* css/CSSFontFaceSrcValue.cpp:
* css/CSSFontFaceSrcValue.h:
(WebCore::CSSFontFaceSrcValue::~CSSFontFaceSrcValue):
* css/CSSFunctionValue.cpp:
* css/CSSFunctionValue.h:
(WebCore::CSSFunctionValue::~CSSFunctionValue):
* css/CSSImageGeneratorValue.h:
* css/CSSImageValue.h:
* css/CSSMutableValue.h:
(WebCore::CSSMutableValue::~CSSMutableValue):
* css/CSSParserValues.h:
* css/CSSPrimitiveValue.h:
* css/CSSUnicodeRangeValue.cpp:
* css/CSSUnicodeRangeValue.h:
(WebCore::CSSUnicodeRangeValue::~CSSUnicodeRangeValue):
* css/CSSValue.cpp:
(WebCore::CSSValue::destroy):
* css/CSSValue.h:
(WebCore::CSSValue::deref):
(WebCore::CSSValue::~CSSValue):
* css/CSSValueList.cpp:
* css/CSSValueList.h:
(WebCore::CSSValueList::~CSSValueList):
* css/WebKitCSSFilterValue.cpp:
* css/WebKitCSSFilterValue.h:
(WebCore::WebKitCSSFilterValue::~WebKitCSSFilterValue):
* css/WebKitCSSTransformValue.cpp:
* css/WebKitCSSTransformValue.h:
(WebCore::WebKitCSSTransformValue::~WebKitCSSTransformValue):

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

33 files changed:
Source/WebCore/ChangeLog
Source/WebCore/css/CSSAspectRatioValue.cpp
Source/WebCore/css/CSSAspectRatioValue.h
Source/WebCore/css/CSSBorderImageSliceValue.cpp
Source/WebCore/css/CSSBorderImageSliceValue.h
Source/WebCore/css/CSSBorderImageValue.cpp
Source/WebCore/css/CSSBorderImageValue.h
Source/WebCore/css/CSSCanvasValue.h
Source/WebCore/css/CSSCrossfadeValue.cpp
Source/WebCore/css/CSSCrossfadeValue.h
Source/WebCore/css/CSSCursorImageValue.h
Source/WebCore/css/CSSFlexValue.cpp
Source/WebCore/css/CSSFlexValue.h
Source/WebCore/css/CSSFontFaceSrcValue.cpp
Source/WebCore/css/CSSFontFaceSrcValue.h
Source/WebCore/css/CSSFunctionValue.cpp
Source/WebCore/css/CSSFunctionValue.h
Source/WebCore/css/CSSImageGeneratorValue.h
Source/WebCore/css/CSSImageValue.h
Source/WebCore/css/CSSMutableValue.h
Source/WebCore/css/CSSParserValues.h
Source/WebCore/css/CSSPrimitiveValue.h
Source/WebCore/css/CSSUnicodeRangeValue.cpp
Source/WebCore/css/CSSUnicodeRangeValue.h
Source/WebCore/css/CSSValue.cpp
Source/WebCore/css/CSSValue.h
Source/WebCore/css/CSSValueList.cpp
Source/WebCore/css/CSSValueList.h
Source/WebCore/css/WebKitCSSFilterValue.cpp
Source/WebCore/css/WebKitCSSFilterValue.h
Source/WebCore/css/WebKitCSSTransformValue.cpp
Source/WebCore/css/WebKitCSSTransformValue.h
Source/WebCore/svg/SVGColor.h

index ea1bfe3..f4d7ae0 100644 (file)
@@ -1,3 +1,67 @@
+2011-11-08  Andreas Kling  <kling@webkit.org>
+
+        Devirtualize CSSValue.
+        <http://webkit.org/b/71666>
+
+        Reviewed by Antti Koivisto.
+
+        Make the CSSValue destructor non-virtual (along with all the subclasses.)
+        This removes the vtables, and the pointers thereto in each value instance,
+        shrinking each object by one CPU word (4 or 8 bytes.)
+
+        We use the same trick as CSSRule to implement destruction; providing our
+        own deref() instead of RefCounted's, and performing a statically typed
+        delete in a destroy() method called when the ref count reaches 0.
+
+        Also made all the empty subclass destructors inline.
+
+        * css/CSSAspectRatioValue.cpp:
+        * css/CSSAspectRatioValue.h:
+        (WebCore::CSSAspectRatioValue::~CSSAspectRatioValue):
+        * css/CSSBorderImageSliceValue.cpp:
+        * css/CSSBorderImageSliceValue.h:
+        (WebCore::CSSBorderImageSliceValue::~CSSBorderImageSliceValue):
+        * css/CSSBorderImageValue.cpp:
+        * css/CSSBorderImageValue.h:
+        (WebCore::CSSBorderImageValue::~CSSBorderImageValue):
+        * css/CSSCanvasValue.h:
+        * css/CSSCrossfadeValue.cpp:
+        * css/CSSCrossfadeValue.h:
+        (WebCore::CSSCrossfadeValue::~CSSCrossfadeValue):
+        * css/CSSCursorImageValue.h:
+        * css/CSSFlexValue.cpp:
+        * css/CSSFlexValue.h:
+        (WebCore::CSSFlexValue::~CSSFlexValue):
+        * css/CSSFontFaceSrcValue.cpp:
+        * css/CSSFontFaceSrcValue.h:
+        (WebCore::CSSFontFaceSrcValue::~CSSFontFaceSrcValue):
+        * css/CSSFunctionValue.cpp:
+        * css/CSSFunctionValue.h:
+        (WebCore::CSSFunctionValue::~CSSFunctionValue):
+        * css/CSSImageGeneratorValue.h:
+        * css/CSSImageValue.h:
+        * css/CSSMutableValue.h:
+        (WebCore::CSSMutableValue::~CSSMutableValue):
+        * css/CSSParserValues.h:
+        * css/CSSPrimitiveValue.h:
+        * css/CSSUnicodeRangeValue.cpp:
+        * css/CSSUnicodeRangeValue.h:
+        (WebCore::CSSUnicodeRangeValue::~CSSUnicodeRangeValue):
+        * css/CSSValue.cpp:
+        (WebCore::CSSValue::destroy):
+        * css/CSSValue.h:
+        (WebCore::CSSValue::deref):
+        (WebCore::CSSValue::~CSSValue):
+        * css/CSSValueList.cpp:
+        * css/CSSValueList.h:
+        (WebCore::CSSValueList::~CSSValueList):
+        * css/WebKitCSSFilterValue.cpp:
+        * css/WebKitCSSFilterValue.h:
+        (WebCore::WebKitCSSFilterValue::~WebKitCSSFilterValue):
+        * css/WebKitCSSTransformValue.cpp:
+        * css/WebKitCSSTransformValue.h:
+        (WebCore::WebKitCSSTransformValue::~WebKitCSSTransformValue):
+
 2011-11-08  Darin Adler  <darin@apple.com>
 
         Speculative fix for crashes seen in DocumentWriter::deprecatedFrameEncoding
index 713a136..18b0ded 100644 (file)
 
 namespace WebCore {
 
-CSSAspectRatioValue::~CSSAspectRatioValue()
-{
-}
-
 String CSSAspectRatioValue::customCssText() const
 {
     StringBuilder result;
index 5ea1404..7567979 100644 (file)
@@ -41,7 +41,7 @@ public:
         return adoptRef(new CSSAspectRatioValue(numeratorValue, denominatorValue));
     }
 
-    virtual ~CSSAspectRatioValue();
+    ~CSSAspectRatioValue() { }
 
     String customCssText() const;
 
index b543e03..04ef2d3 100644 (file)
@@ -38,10 +38,6 @@ CSSBorderImageSliceValue::CSSBorderImageSliceValue(PassRefPtr<CSSPrimitiveValue>
 {
 }
 
-CSSBorderImageSliceValue::~CSSBorderImageSliceValue()
-{
-}
-
 String CSSBorderImageSliceValue::customCssText() const
 {
     // Dump the slices first.
index af120ac..45c9f97 100644 (file)
@@ -40,7 +40,7 @@ public:
     {
         return adoptRef(new CSSBorderImageSliceValue(slices, fill));
     }
-    virtual ~CSSBorderImageSliceValue();
+    ~CSSBorderImageSliceValue() { }
 
     String customCssText() const;
 
index 8ff6bc8..846ea6d 100644 (file)
@@ -37,10 +37,6 @@ CSSBorderImageValue::CSSBorderImageValue(PassRefPtr<CSSValue> image, PassRefPtr<
 {
 }
 
-CSSBorderImageValue::~CSSBorderImageValue()
-{
-}
-
 String CSSBorderImageValue::customCssText() const
 {
     // Image first.
index 1b80d6b..406c994 100644 (file)
@@ -36,7 +36,7 @@ public:
     {
         return adoptRef(new CSSBorderImageValue(image, imageSlice, borderSlice, outset, repeat));
     }
-    virtual ~CSSBorderImageValue();
+    ~CSSBorderImageValue() { }
 
     String customCssText() const;
 
index 101b580..232a525 100644 (file)
@@ -36,7 +36,7 @@ class Document;
 class CSSCanvasValue : public CSSImageGeneratorValue {
 public:
     static PassRefPtr<CSSCanvasValue> create() { return adoptRef(new CSSCanvasValue); }
-    virtual ~CSSCanvasValue();
+    ~CSSCanvasValue();
 
     String customCssText() const;
 
index 14c250c..b77069f 100644 (file)
 
 namespace WebCore {
 
-CSSCrossfadeValue::~CSSCrossfadeValue()
-{
-
-}
-
 String CSSCrossfadeValue::customCssText() const
 {
     String result = "-webkit-cross-fade(";
index f2a4ad7..9bb4bb6 100644 (file)
@@ -38,7 +38,7 @@ class RenderObject;
 class CSSCrossfadeValue : public CSSImageGeneratorValue {
 public:
     static PassRefPtr<CSSCrossfadeValue> create(PassRefPtr<CSSImageValue> fromImage, PassRefPtr<CSSImageValue> toImage) { return adoptRef(new CSSCrossfadeValue(fromImage, toImage)); }
-    virtual ~CSSCrossfadeValue();
+    ~CSSCrossfadeValue() { }
 
     String customCssText() const;
 
index 3c03413..cb26919 100644 (file)
@@ -37,7 +37,7 @@ public:
         return adoptRef(new CSSCursorImageValue(url, hotSpot));
     }
 
-    virtual ~CSSCursorImageValue();
+    ~CSSCursorImageValue();
 
     IntPoint hotSpot() const { return m_hotSpot; }
 
index 6bd312c..c2bc53c 100644 (file)
 
 namespace WebCore {
 
-CSSFlexValue::~CSSFlexValue()
-{
-}
-
 String CSSFlexValue::customCssText() const
 {
     StringBuilder result;
index 99099d9..3e568e4 100644 (file)
@@ -43,7 +43,7 @@ public:
         return adoptRef(new CSSFlexValue(positiveFlex, negativeFlex, preferredSize));
     }
 
-    virtual ~CSSFlexValue();
+    ~CSSFlexValue() { }
 
     String customCssText() const;
 
index 0567ff4..57300ef 100644 (file)
 
 namespace WebCore {
 
-CSSFontFaceSrcValue::~CSSFontFaceSrcValue()
-{
-}
-
 #if ENABLE(SVG_FONTS)
 bool CSSFontFaceSrcValue::isSVGFontFaceSrc() const
 {
index f036978..8303290 100644 (file)
@@ -45,7 +45,7 @@ public:
         return adoptRef(new CSSFontFaceSrcValue(resource, true));
     }
 
-    virtual ~CSSFontFaceSrcValue();
+    ~CSSFontFaceSrcValue() { }
 
     const String& resource() const { return m_resource; }
     const String& format() const { return m_format; }
index c31ab0a..522ad9f 100644 (file)
@@ -40,10 +40,6 @@ CSSFunctionValue::CSSFunctionValue(CSSParserFunction* function)
         m_args = CSSValueList::createFromParserValueList(function->args.get());
 }
 
-CSSFunctionValue::~CSSFunctionValue()
-{
-}
-
 String CSSFunctionValue::customCssText() const
 {
     String result = m_name; // Includes the '('
index 4505093..6cc5947 100644 (file)
@@ -40,7 +40,7 @@ public:
         return adoptRef(new CSSFunctionValue(function));
     }
 
-    virtual ~CSSFunctionValue();
+    ~CSSFunctionValue() { }
 
     String customCssText() const;
 
index a4c29ae..d0eb65b 100644 (file)
@@ -52,7 +52,7 @@ typedef HashMap<const RenderObject*, SizeAndCount> RenderObjectSizeCountMap;
 
 class CSSImageGeneratorValue : public CSSValue {
 public:
-    virtual ~CSSImageGeneratorValue();
+    ~CSSImageGeneratorValue();
 
     void addClient(RenderObject*, const IntSize&);
     void removeClient(RenderObject*);
index ffe0076..328b6c9 100644 (file)
@@ -35,7 +35,7 @@ class CSSImageValue : public CSSPrimitiveValue {
 public:
     static PassRefPtr<CSSImageValue> create() { return adoptRef(new CSSImageValue); }
     static PassRefPtr<CSSImageValue> create(const String& url) { return adoptRef(new CSSImageValue(url)); }
-    virtual ~CSSImageValue();
+    ~CSSImageValue();
 
     StyleCachedImage* cachedImage(CachedResourceLoader*);
     // Returns a StyleCachedImage if the image is cached already, otherwise a StylePendingImage.
index 74ea5ee..f2631b1 100644 (file)
@@ -27,7 +27,7 @@ namespace WebCore {
 
 class CSSMutableValue : public CSSValue {
 public:
-    virtual ~CSSMutableValue() { }
+    ~CSSMutableValue() { }
 
     Node* node() const { return m_node; }
     void setNode(Node* node) { m_node = node; }
index cb5c903..90d26a4 100644 (file)
@@ -22,6 +22,7 @@
 #define CSSParserValues_h
 
 #include "CSSSelector.h"
+#include "CSSValueList.h"
 #include <wtf/text/AtomicString.h>
 
 namespace WebCore {
index 180de6d..fedab8c 100644 (file)
@@ -143,7 +143,7 @@ public:
         return adoptRef(quirkValue);
     }
 
-    virtual ~CSSPrimitiveValue();
+    ~CSSPrimitiveValue();
 
     void cleanup();
 
index a1a2b82..2c2c44d 100644 (file)
 
 namespace WebCore {
 
-CSSUnicodeRangeValue::~CSSUnicodeRangeValue()
-{
-}
-
 String CSSUnicodeRangeValue::customCssText() const
 {
     String result;
index a8b4a38..2895db0 100644 (file)
@@ -39,7 +39,7 @@ public:
         return adoptRef(new CSSUnicodeRangeValue(from, to));
     }
 
-    virtual ~CSSUnicodeRangeValue();
+    ~CSSUnicodeRangeValue() { }
 
     UChar32 from() const { return m_from; }
     UChar32 to() const { return m_to; }
index ea94e1e..3c92bd9 100644 (file)
@@ -160,4 +160,108 @@ String CSSValue::cssText() const
     return String();
 }
 
+void CSSValue::destroy()
+{
+    switch (classType()) {
+    case AspectRatioClass:
+        delete static_cast<CSSAspectRatioValue*>(this);
+        return;
+    case BorderImageClass:
+        delete static_cast<CSSBorderImageValue*>(this);
+        return;
+    case BorderImageSliceClass:
+        delete static_cast<CSSBorderImageSliceValue*>(this);
+        return;
+    case CanvasClass:
+        delete static_cast<CSSCanvasValue*>(this);
+        return;
+    case CursorImageClass:
+        delete static_cast<CSSCursorImageValue*>(this);
+        return;
+    case FontClass:
+        delete static_cast<FontValue*>(this);
+        return;
+    case FontFaceSrcClass:
+        delete static_cast<CSSFontFaceSrcValue*>(this);
+        return;
+    case FontFamilyClass:
+        delete static_cast<FontFamilyValue*>(this);
+        return;
+    case FontFeatureClass:
+        delete static_cast<FontFeatureValue*>(this);
+        return;
+    case FunctionClass:
+        delete static_cast<CSSFunctionValue*>(this);
+        return;
+    case LinearGradientClass:
+        delete static_cast<CSSLinearGradientValue*>(this);
+        return;
+    case RadialGradientClass:
+        delete static_cast<CSSRadialGradientValue*>(this);
+        return;
+    case CrossfadeClass:
+        delete static_cast<CSSCrossfadeValue*>(this);
+        return;
+    case ImageClass:
+        delete static_cast<CSSImageValue*>(this);
+        return;
+    case InheritedClass:
+        delete static_cast<CSSInheritedValue*>(this);
+        return;
+    case InitialClass:
+    case ImplicitInitialClass:
+        delete static_cast<CSSInitialValue*>(this);
+        return;
+    case PrimitiveClass:
+        delete static_cast<CSSPrimitiveValue*>(this);
+        return;
+    case ReflectClass:
+        delete static_cast<CSSReflectValue*>(this);
+        return;
+    case ShadowClass:
+        delete static_cast<ShadowValue*>(this);
+        return;
+    case LinearTimingFunctionClass:
+        delete static_cast<CSSLinearTimingFunctionValue*>(this);
+        return;
+    case CubicBezierTimingFunctionClass:
+        delete static_cast<CSSCubicBezierTimingFunctionValue*>(this);
+        return;
+    case StepsTimingFunctionClass:
+        delete static_cast<CSSStepsTimingFunctionValue*>(this);
+        return;
+    case UnicodeRangeClass:
+        delete static_cast<CSSUnicodeRangeValue*>(this);
+        return;
+    case ValueListClass:
+        delete static_cast<CSSValueList*>(this);
+        return;
+    case WebKitCSSTransformClass:
+        delete static_cast<WebKitCSSTransformValue*>(this);
+        return;
+    case LineBoxContainClass:
+        delete static_cast<CSSLineBoxContainValue*>(this);
+        return;
+#if ENABLE(CSS3_FLEXBOX)
+    case FlexClass:
+        delete static_cast<CSSFlexValue*>(this);
+        return;
+#endif
+#if ENABLE(CSS_FILTERS)
+    case WebKitCSSFilterClass:
+        delete static_cast<WebKitCSSFilterValue*>(this);
+        return;
+#endif
+#if ENABLE(SVG)
+    case SVGColorClass:
+        delete static_cast<SVGColor*>(this);
+        return;
+    case SVGPaintClass:
+        delete static_cast<SVGPaint*>(this);
+        return;
+#endif
+    }
+    ASSERT_NOT_REACHED();
+}
+
 }
index 26530d1..41d545a 100644 (file)
@@ -40,9 +40,16 @@ public:
         CSS_VALUE_LIST = 2,
         CSS_CUSTOM = 3,
         CSS_INITIAL = 4
+
     };
 
-    virtual ~CSSValue() { }
+    // Override RefCounted's deref() to ensure operator delete is called on
+    // the appropriate subclass type.
+    void deref()
+    {
+        if (derefBase())
+            destroy();
+    }
 
     Type cssValueType() const;
 
@@ -136,6 +143,11 @@ protected:
     {
     }
 
+    // NOTE: This class is non-virtual for memory and performance reasons.
+    // Don't go making it virtual again unless you know exactly what you're doing!
+
+    ~CSSValue() { }
+
 private:
     static bool isPrimitiveType(ClassType type)
     {
@@ -175,6 +187,8 @@ private:
         return type == InitialClass || type == ImplicitInitialClass;
     }
 
+    void destroy();
+
     // FIXME: This class is currently a little bloated, but that will change.
     //        See <http://webkit.org/b/71666> for more information.
     unsigned m_classType : 5; // ClassType
index 7a288b6..8b821c6 100644 (file)
@@ -50,10 +50,6 @@ CSSValueList::CSSValueList(CSSParserValueList* list)
     }
 }
 
-CSSValueList::~CSSValueList()
-{
-}
-
 void CSSValueList::append(PassRefPtr<CSSValue> val)
 {
     m_values.append(val);
index 22abf3b..7f1b99b 100644 (file)
@@ -44,7 +44,7 @@ public:
         return adoptRef(new CSSValueList(list));
     }
 
-    virtual ~CSSValueList();
+    ~CSSValueList() { }
 
     size_t length() const { return m_values.size(); }
     CSSValue* item(size_t index) { return index < m_values.size() ? m_values[index].get() : 0; }
index 71ec327..64feb8c 100644 (file)
@@ -40,10 +40,6 @@ WebKitCSSFilterValue::WebKitCSSFilterValue(FilterOperationType operationType)
 {
 }
 
-WebKitCSSFilterValue::~WebKitCSSFilterValue()
-{
-}
-
 String WebKitCSSFilterValue::customCssText() const
 {
     String result;
index cfb4c8b..fb86bd5 100644 (file)
@@ -57,7 +57,7 @@ public:
         return adoptRef(new WebKitCSSFilterValue(type));
     }
 
-    virtual ~WebKitCSSFilterValue();
+    ~WebKitCSSFilterValue() { }
 
     String customCssText() const;
 
index 6e0cdd5..6a391ac 100644 (file)
@@ -38,10 +38,6 @@ WebKitCSSTransformValue::WebKitCSSTransformValue(TransformOperationType op)
 {
 }
 
-WebKitCSSTransformValue::~WebKitCSSTransformValue()
-{
-}
-
 String WebKitCSSTransformValue::customCssText() const
 {
     String result;
index 8a5e6d8..db0688b 100644 (file)
@@ -65,7 +65,7 @@ public:
         return adoptRef(new WebKitCSSTransformValue(type));
     }
 
-    virtual ~WebKitCSSTransformValue();
+    ~WebKitCSSTransformValue() { }
 
     String customCssText() const;
 
index 8ef3e3a..746ca03 100644 (file)
@@ -71,11 +71,12 @@ public:
 
     String customCssText() const;
 
+    ~SVGColor() { }
+
 protected:
     friend class CSSComputedStyleDeclaration;
 
     SVGColor(ClassType, const SVGColorType&);
-    virtual ~SVGColor() { }
 
     void setColor(const Color& color) { m_color = color; }
     void setColorType(const SVGColorType& type) { m_colorType = type; }