Title: [142404] trunk/Source/WebCore
Revision
142404
Author
[email protected]
Date
2013-02-10 08:04:43 -0800 (Sun, 10 Feb 2013)

Log Message

RenderStyle should use copy-on-write inheritance for NinePieceImage.
<http://webkit.org/b/109366>

Reviewed by Antti Koivisto.

Refactor NinePieceImage to hold a copy-on-write DataRef like other RenderStyle substructures.
This allows us to avoids copying the NinePieceImageData when one RenderStyle inherits from another
but modifies something in the substructure holding the NinePieceImage (typically StyleSurroundData.)

Also made RenderStyle not copy-on-write its StyleSurroundData prematurely when doing a no-op write
to a border-image related value.

1.23 MB progression on Membuster3.

* rendering/style/NinePieceImage.cpp:
(WebCore::defaultData):
(WebCore::NinePieceImage::NinePieceImage):
(WebCore::NinePieceImageData::NinePieceImageData):
(WebCore::NinePieceImageData::operator==):
* rendering/style/NinePieceImage.h:
(WebCore::NinePieceImageData::create):
(WebCore::NinePieceImageData::copy):
(NinePieceImageData):
(NinePieceImage):
(WebCore::NinePieceImage::operator==):
(WebCore::NinePieceImage::operator!=):
(WebCore::NinePieceImage::hasImage):
(WebCore::NinePieceImage::image):
(WebCore::NinePieceImage::setImage):
(WebCore::NinePieceImage::imageSlices):
(WebCore::NinePieceImage::setImageSlices):
(WebCore::NinePieceImage::fill):
(WebCore::NinePieceImage::setFill):
(WebCore::NinePieceImage::borderSlices):
(WebCore::NinePieceImage::setBorderSlices):
(WebCore::NinePieceImage::outset):
(WebCore::NinePieceImage::setOutset):
(WebCore::NinePieceImage::horizontalRule):
(WebCore::NinePieceImage::setHorizontalRule):
(WebCore::NinePieceImage::verticalRule):
(WebCore::NinePieceImage::setVerticalRule):
(WebCore::NinePieceImage::copyImageSlicesFrom):
(WebCore::NinePieceImage::copyBorderSlicesFrom):
(WebCore::NinePieceImage::copyOutsetFrom):
(WebCore::NinePieceImage::copyRepeatFrom):
(WebCore::NinePieceImage::setMaskDefaults):
(WebCore::NinePieceImage::computeOutset):
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::setBorderImageSource):
(WebCore::RenderStyle::setBorderImageSlices):
(WebCore::RenderStyle::setBorderImageWidth):
(WebCore::RenderStyle::setBorderImageOutset):
* rendering/style/RenderStyle.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (142403 => 142404)


--- trunk/Source/WebCore/ChangeLog	2013-02-10 15:05:44 UTC (rev 142403)
+++ trunk/Source/WebCore/ChangeLog	2013-02-10 16:04:43 UTC (rev 142404)
@@ -1,3 +1,59 @@
+2013-02-10  Andreas Kling  <[email protected]>
+
+        RenderStyle should use copy-on-write inheritance for NinePieceImage.
+        <http://webkit.org/b/109366>
+
+        Reviewed by Antti Koivisto.
+
+        Refactor NinePieceImage to hold a copy-on-write DataRef like other RenderStyle substructures.
+        This allows us to avoids copying the NinePieceImageData when one RenderStyle inherits from another
+        but modifies something in the substructure holding the NinePieceImage (typically StyleSurroundData.)
+
+        Also made RenderStyle not copy-on-write its StyleSurroundData prematurely when doing a no-op write
+        to a border-image related value.
+
+        1.23 MB progression on Membuster3.
+
+        * rendering/style/NinePieceImage.cpp:
+        (WebCore::defaultData):
+        (WebCore::NinePieceImage::NinePieceImage):
+        (WebCore::NinePieceImageData::NinePieceImageData):
+        (WebCore::NinePieceImageData::operator==):
+        * rendering/style/NinePieceImage.h:
+        (WebCore::NinePieceImageData::create):
+        (WebCore::NinePieceImageData::copy):
+        (NinePieceImageData):
+        (NinePieceImage):
+        (WebCore::NinePieceImage::operator==):
+        (WebCore::NinePieceImage::operator!=):
+        (WebCore::NinePieceImage::hasImage):
+        (WebCore::NinePieceImage::image):
+        (WebCore::NinePieceImage::setImage):
+        (WebCore::NinePieceImage::imageSlices):
+        (WebCore::NinePieceImage::setImageSlices):
+        (WebCore::NinePieceImage::fill):
+        (WebCore::NinePieceImage::setFill):
+        (WebCore::NinePieceImage::borderSlices):
+        (WebCore::NinePieceImage::setBorderSlices):
+        (WebCore::NinePieceImage::outset):
+        (WebCore::NinePieceImage::setOutset):
+        (WebCore::NinePieceImage::horizontalRule):
+        (WebCore::NinePieceImage::setHorizontalRule):
+        (WebCore::NinePieceImage::verticalRule):
+        (WebCore::NinePieceImage::setVerticalRule):
+        (WebCore::NinePieceImage::copyImageSlicesFrom):
+        (WebCore::NinePieceImage::copyBorderSlicesFrom):
+        (WebCore::NinePieceImage::copyOutsetFrom):
+        (WebCore::NinePieceImage::copyRepeatFrom):
+        (WebCore::NinePieceImage::setMaskDefaults):
+        (WebCore::NinePieceImage::computeOutset):
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::setBorderImageSource):
+        (WebCore::RenderStyle::setBorderImageSlices):
+        (WebCore::RenderStyle::setBorderImageWidth):
+        (WebCore::RenderStyle::setBorderImageOutset):
+        * rendering/style/RenderStyle.h:
+
 2013-02-10  Kent Tamura  <[email protected]>
 
         Unreviewed, rolling out r142343.

Modified: trunk/Source/WebCore/rendering/style/NinePieceImage.cpp (142403 => 142404)


--- trunk/Source/WebCore/rendering/style/NinePieceImage.cpp	2013-02-10 15:05:44 UTC (rev 142403)
+++ trunk/Source/WebCore/rendering/style/NinePieceImage.cpp	2013-02-10 16:04:43 UTC (rev 142404)
@@ -2,7 +2,7 @@
  * Copyright (C) 2000 Lars Knoll ([email protected])
  *           (C) 2000 Antti Koivisto ([email protected])
  *           (C) 2000 Dirk Mueller ([email protected])
- * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -26,16 +26,63 @@
 
 namespace WebCore {
 
-bool NinePieceImageData::operator==(const NinePieceImageData& o) const
+static DataRef<NinePieceImageData>& defaultData()
 {
-    return StyleImage::imagesEquivalent(m_image.get(), o.m_image.get()) && m_imageSlices == o.m_imageSlices && m_fill == o.m_fill
-           && m_borderSlices == o.m_borderSlices && m_outset == o.m_outset && m_horizontalRule == o.m_horizontalRule && m_verticalRule == o.m_verticalRule;
+    static DataRef<NinePieceImageData>* data = "" DataRef<NinePieceImageData>;
+    if (!data->get())
+        data->init();
+    return *data;
 }
 
-const NinePieceImageData& NinePieceImage::defaultData()
+NinePieceImage::NinePieceImage()
+    : m_data(defaultData())
 {
-    DEFINE_STATIC_LOCAL(NinePieceImageData, data, ());
-    return data;
 }
 
+NinePieceImage::NinePieceImage(PassRefPtr<StyleImage> image, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule horizontalRule, ENinePieceImageRule verticalRule)
+{
+    m_data.init();
+    m_data.access()->image = image;
+    m_data.access()->imageSlices = imageSlices;
+    m_data.access()->borderSlices = borderSlices;
+    m_data.access()->outset = outset;
+    m_data.access()->fill = fill;
+    m_data.access()->horizontalRule = horizontalRule;
+    m_data.access()->verticalRule = verticalRule;
 }
+
+NinePieceImageData::NinePieceImageData()
+    : fill(false)
+    , horizontalRule(StretchImageRule)
+    , verticalRule(StretchImageRule)
+    , image(0)
+    , imageSlices(Length(100, Percent), Length(100, Percent), Length(100, Percent), Length(100, Percent))
+    , borderSlices(Length(1, Relative), Length(1, Relative), Length(1, Relative), Length(1, Relative))
+    , outset(0)
+{
+}
+
+NinePieceImageData::NinePieceImageData(const NinePieceImageData& other)
+    : RefCounted<NinePieceImageData>()
+    , fill(other.fill)
+    , horizontalRule(other.horizontalRule)
+    , verticalRule(other.verticalRule)
+    , image(other.image)
+    , imageSlices(other.imageSlices)
+    , borderSlices(other.borderSlices)
+    , outset(other.outset)
+{
+}
+
+bool NinePieceImageData::operator==(const NinePieceImageData& other) const
+{
+    return StyleImage::imagesEquivalent(image.get(), other.image.get())
+        && imageSlices == other.imageSlices
+        && fill == other.fill
+        && borderSlices == other.borderSlices
+        && outset == other.outset
+        && horizontalRule == other.horizontalRule
+        && verticalRule == other.verticalRule;
+}
+
+}

Modified: trunk/Source/WebCore/rendering/style/NinePieceImage.h (142403 => 142404)


--- trunk/Source/WebCore/rendering/style/NinePieceImage.h	2013-02-10 15:05:44 UTC (rev 142403)
+++ trunk/Source/WebCore/rendering/style/NinePieceImage.h	2013-02-10 16:04:43 UTC (rev 142404)
@@ -2,7 +2,7 @@
  * Copyright (C) 2000 Lars Knoll ([email protected])
  *           (C) 2000 Antti Koivisto ([email protected])
  *           (C) 2000 Dirk Mueller ([email protected])
- * Copyright (C) 2003, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -24,6 +24,7 @@
 #ifndef NinePieceImage_h
 #define NinePieceImage_h
 
+#include "DataRef.h"
 #include "LayoutUnit.h"
 #include "LengthBox.h"
 #include "StyleImage.h"
@@ -34,149 +35,95 @@
     StretchImageRule, RoundImageRule, SpaceImageRule, RepeatImageRule
 };
 
-class NinePieceImageData {
-    WTF_MAKE_FAST_ALLOCATED;
+class NinePieceImageData : public RefCounted<NinePieceImageData> {
 public:
-    NinePieceImageData()
-        : m_image(0)
-        , m_imageSlices(Length(100, Percent), Length(100, Percent), Length(100, Percent), Length(100, Percent))
-        , m_borderSlices(Length(1, Relative), Length(1, Relative), Length(1, Relative), Length(1, Relative))
-        , m_outset(0)
-        , m_fill(false)
-        , m_horizontalRule(StretchImageRule)
-        , m_verticalRule(StretchImageRule)
-    {
-    }
+    static PassRefPtr<NinePieceImageData> create() { return adoptRef(new NinePieceImageData); }
+    PassRefPtr<NinePieceImageData> copy() const { return adoptRef(new NinePieceImageData(*this)); }
 
-    NinePieceImageData(PassRefPtr<StyleImage> image, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule h, ENinePieceImageRule v)
-      : m_image(image)
-      , m_imageSlices(imageSlices)
-      , m_borderSlices(borderSlices)
-      , m_outset(outset)
-      , m_fill(fill)
-      , m_horizontalRule(h)
-      , m_verticalRule(v)
-    {
-    }
-
     bool operator==(const NinePieceImageData&) const;
     bool operator!=(const NinePieceImageData& o) const { return !(*this == o); }
 
-    RefPtr<StyleImage> m_image;
-    LengthBox m_imageSlices;
-    LengthBox m_borderSlices;
-    LengthBox m_outset;
-    bool m_fill : 1;
-    unsigned m_horizontalRule : 2; // ENinePieceImageRule
-    unsigned m_verticalRule : 2; // ENinePieceImageRule
+    bool fill : 1;
+    unsigned horizontalRule : 2; // ENinePieceImageRule
+    unsigned verticalRule : 2; // ENinePieceImageRule
+    RefPtr<StyleImage> image;
+    LengthBox imageSlices;
+    LengthBox borderSlices;
+    LengthBox outset;
+
+private:
+    NinePieceImageData();
+    NinePieceImageData(const NinePieceImageData&);
 };
 
 class NinePieceImage {
 public:
-    NinePieceImage() { }
+    NinePieceImage();
+    NinePieceImage(PassRefPtr<StyleImage>, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule horizontalRule, ENinePieceImageRule verticalRule);
 
-    NinePieceImage(PassRefPtr<StyleImage> image, LengthBox imageSlices, bool fill, LengthBox borderSlices, LengthBox outset, ENinePieceImageRule h, ENinePieceImageRule v)
-        : m_data(adoptPtr(new NinePieceImageData(image, imageSlices, fill, borderSlices, outset, h, v)))
-    { }
+    bool operator==(const NinePieceImage& other) const { return m_data == other.m_data; }
+    bool operator!=(const NinePieceImage& other) const { return m_data != other.m_data; }
 
-    NinePieceImage(const NinePieceImage& other)
-    {
-        *this = other;
-    }
-
-    void operator=(const NinePieceImage& other)
-    {
-        if (!other.m_data) {
-            m_data.clear();
-            return;
-        }
-        const NinePieceImageData& otherData = other.data();
-        m_data = adoptPtr(new NinePieceImageData(otherData.m_image, otherData.m_imageSlices, otherData.m_fill, otherData.m_borderSlices, otherData.m_outset, static_cast<ENinePieceImageRule>(otherData.m_horizontalRule), static_cast<ENinePieceImageRule>(otherData.m_verticalRule)));
-    }
-
-    bool operator==(const NinePieceImage& other) const { return data() == other.data(); }
-    bool operator!=(const NinePieceImage& other) const { return !(*this == other); }
-
-    bool hasImage() const { return m_data && m_data->m_image; }
-    StyleImage* image() const { return m_data ? m_data->m_image.get() : 0; }
-    void setImage(PassRefPtr<StyleImage> image) { ensureData(); m_data->m_image = image; }
+    bool hasImage() const { return m_data->image; }
+    StyleImage* image() const { return m_data->image.get(); }
+    void setImage(PassRefPtr<StyleImage> image) { m_data.access()->image = image; }
     
-    const LengthBox& imageSlices() const { return data().m_imageSlices; }
-    void setImageSlices(const LengthBox& slices) { ensureData(); m_data->m_imageSlices = slices; }
+    const LengthBox& imageSlices() const { return m_data->imageSlices; }
+    void setImageSlices(const LengthBox& slices) { m_data.access()->imageSlices = slices; }
 
-    bool fill() const { return data().m_fill; }
-    void setFill(bool fill) { ensureData(); m_data->m_fill = fill; }
+    bool fill() const { return m_data->fill; }
+    void setFill(bool fill) { m_data.access()->fill = fill; }
 
-    const LengthBox& borderSlices() const { return data().m_borderSlices; }
-    void setBorderSlices(const LengthBox& slices) { ensureData(); m_data->m_borderSlices = slices; }
+    const LengthBox& borderSlices() const { return m_data->borderSlices; }
+    void setBorderSlices(const LengthBox& slices) { m_data.access()->borderSlices = slices; }
 
-    const LengthBox& outset() const { return data().m_outset; }
-    void setOutset(const LengthBox& outset) { ensureData(); m_data->m_outset = outset; }
-    
-    static LayoutUnit computeOutset(Length outsetSide, LayoutUnit borderSide)
-    {
-        if (outsetSide.isRelative())
-            return outsetSide.value() * borderSide;
-        return outsetSide.value();
-    }
+    const LengthBox& outset() const { return m_data->outset; }
+    void setOutset(const LengthBox& outset) { m_data.access()->outset = outset; }
 
-    ENinePieceImageRule horizontalRule() const { return static_cast<ENinePieceImageRule>(data().m_horizontalRule); }
-    void setHorizontalRule(ENinePieceImageRule rule) { ensureData(); m_data->m_horizontalRule = rule; }
+    ENinePieceImageRule horizontalRule() const { return static_cast<ENinePieceImageRule>(m_data->horizontalRule); }
+    void setHorizontalRule(ENinePieceImageRule rule) { m_data.access()->horizontalRule = rule; }
     
-    ENinePieceImageRule verticalRule() const { return static_cast<ENinePieceImageRule>(data().m_verticalRule); }
-    void setVerticalRule(ENinePieceImageRule rule) { ensureData(); m_data->m_verticalRule = rule; }
+    ENinePieceImageRule verticalRule() const { return static_cast<ENinePieceImageRule>(m_data->verticalRule); }
+    void setVerticalRule(ENinePieceImageRule rule) { m_data.access()->verticalRule = rule; }
 
     void copyImageSlicesFrom(const NinePieceImage& other)
     {
-        ensureData();
-        m_data->m_imageSlices = other.data().m_imageSlices;
-        m_data->m_fill = other.data().m_fill;
+        m_data.access()->imageSlices = other.m_data->imageSlices;
+        m_data.access()->fill = other.m_data->fill;
     }
 
     void copyBorderSlicesFrom(const NinePieceImage& other)
     {
-        ensureData();
-        m_data->m_borderSlices = other.data().m_borderSlices;
+        m_data.access()->borderSlices = other.m_data->borderSlices;
     }
     
     void copyOutsetFrom(const NinePieceImage& other)
     {
-        ensureData();
-        m_data->m_outset = other.data().m_outset;
+        m_data.access()->outset = other.m_data->outset;
     }
 
     void copyRepeatFrom(const NinePieceImage& other)
     {
-        ensureData();
-        m_data->m_horizontalRule = other.data().m_horizontalRule;
-        m_data->m_verticalRule = other.data().m_verticalRule;
+        m_data.access()->horizontalRule = other.m_data->horizontalRule;
+        m_data.access()->verticalRule = other.m_data->verticalRule;
     }
 
     void setMaskDefaults()
     {
-        ensureData();
-        m_data->m_imageSlices = LengthBox(0);
-        m_data->m_fill = true;
-        m_data->m_borderSlices = LengthBox();
+        m_data.access()->imageSlices = LengthBox(0);
+        m_data.access()->fill = true;
+        m_data.access()->borderSlices = LengthBox();
     }
 
-private:
-    static const NinePieceImageData& defaultData();
-
-    void ensureData()
+    static LayoutUnit computeOutset(Length outsetSide, LayoutUnit borderSide)
     {
-        if (!m_data)
-            m_data = adoptPtr(new NinePieceImageData);
+        if (outsetSide.isRelative())
+            return outsetSide.value() * borderSide;
+        return outsetSide.value();
     }
 
-    const NinePieceImageData& data() const
-    {
-        if (m_data)
-            return *m_data;
-        return defaultData();
-    }
-
-    OwnPtr<NinePieceImageData> m_data;
+private:
+    DataRef<NinePieceImageData> m_data;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/style/RenderStyle.cpp (142403 => 142404)


--- trunk/Source/WebCore/rendering/style/RenderStyle.cpp	2013-02-10 15:05:44 UTC (rev 142403)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.cpp	2013-02-10 16:04:43 UTC (rev 142404)
@@ -1606,6 +1606,34 @@
                            NinePieceImage::computeOutset(image.outset().left(), borderLeftWidth()));
 }
 
+void RenderStyle::setBorderImageSource(PassRefPtr<StyleImage> image)
+{
+    if (surround->border.m_image.image() == image.get())
+        return;
+    surround.access()->border.m_image.setImage(image);
+}
+
+void RenderStyle::setBorderImageSlices(LengthBox slices)
+{
+    if (surround->border.m_image.imageSlices() == slices)
+        return;
+    surround.access()->border.m_image.setImageSlices(slices);
+}
+
+void RenderStyle::setBorderImageWidth(LengthBox slices)
+{
+    if (surround->border.m_image.borderSlices() == slices)
+        return;
+    surround.access()->border.m_image.setBorderSlices(slices);
+}
+
+void RenderStyle::setBorderImageOutset(LengthBox outset)
+{
+    if (surround->border.m_image.outset() == outset)
+        return;
+    surround.access()->border.m_image.setOutset(outset);
+}
+
 void RenderStyle::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::CSS);

Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (142403 => 142404)


--- trunk/Source/WebCore/rendering/style/RenderStyle.h	2013-02-10 15:05:44 UTC (rev 142403)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h	2013-02-10 16:04:43 UTC (rev 142404)
@@ -1020,10 +1020,10 @@
     void setBackgroundSizeLength(LengthSize s) { SET_VAR(m_background, m_background.m_sizeLength, s); }
     
     void setBorderImage(const NinePieceImage& b) { SET_VAR(surround, border.m_image, b); }
-    void setBorderImageSource(PassRefPtr<StyleImage> v) { surround.access()->border.m_image.setImage(v); }
-    void setBorderImageSlices(LengthBox slices) { surround.access()->border.m_image.setImageSlices(slices); }
-    void setBorderImageWidth(LengthBox slices) { surround.access()->border.m_image.setBorderSlices(slices); }
-    void setBorderImageOutset(LengthBox outset) { surround.access()->border.m_image.setOutset(outset); }
+    void setBorderImageSource(PassRefPtr<StyleImage>);
+    void setBorderImageSlices(LengthBox);
+    void setBorderImageWidth(LengthBox);
+    void setBorderImageOutset(LengthBox);
 
     void setBorderTopLeftRadius(LengthSize s) { SET_VAR(surround, border.m_topLeft, s); }
     void setBorderTopRightRadius(LengthSize s) { SET_VAR(surround, border.m_topRight, s); }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to