Modified: trunk/Source/WebCore/css/CSSParser.cpp (118808 => 118809)
--- trunk/Source/WebCore/css/CSSParser.cpp 2012-05-29 18:15:03 UTC (rev 118808)
+++ trunk/Source/WebCore/css/CSSParser.cpp 2012-05-29 18:19:59 UTC (rev 118809)
@@ -1200,7 +1200,7 @@
if (unusedEntries)
results.remove(0, unusedEntries);
- return StylePropertySet::adopt(results, m_context.mode);
+ return StylePropertySet::createImmutable(results, m_context.mode);
}
void CSSParser::addProperty(CSSPropertyID propId, PassRefPtr<CSSValue> value, bool important, bool implicit)
Modified: trunk/Source/WebCore/css/StylePropertySet.cpp (118808 => 118809)
--- trunk/Source/WebCore/css/StylePropertySet.cpp 2012-05-29 18:15:03 UTC (rev 118808)
+++ trunk/Source/WebCore/css/StylePropertySet.cpp 2012-05-29 18:19:59 UTC (rev 118809)
@@ -50,31 +50,45 @@
return propertySetCSSOMWrapperMapInstance;
}
+PassRefPtr<StylePropertySet> StylePropertySet::createImmutable(StylePropertyVector& properties, CSSParserMode cssParserMode)
+{
+ void* slot = WTF::fastMalloc(sizeof(StylePropertySet) - sizeof(void*) + sizeof(CSSProperty) * properties.size());
+ return adoptRef(new (slot) StylePropertySet(properties, cssParserMode, /* makeMutable */ false));
+}
+
StylePropertySet::StylePropertySet(CSSParserMode cssParserMode)
: m_cssParserMode(cssParserMode)
, m_ownsCSSOMWrapper(false)
, m_isMutable(true)
+ , m_arraySize(0)
+ , m_mutablePropertyVector(new Vector<CSSProperty>)
{
}
-StylePropertySet::StylePropertySet(StylePropertyVector& properties, CSSParserMode cssParserMode)
+StylePropertySet::StylePropertySet(StylePropertyVector& properties, CSSParserMode cssParserMode, bool makeMutable)
: m_cssParserMode(cssParserMode)
, m_ownsCSSOMWrapper(false)
- , m_isMutable(false)
+ , m_isMutable(makeMutable)
{
- m_properties.swap(properties);
-
- // This shrinkToFit() will be a no-op in the typical case (no duplicate properties were eliminated after parsing.)
- m_properties.shrinkToFit();
+ if (makeMutable) {
+ m_mutablePropertyVector = new Vector<CSSProperty>;
+ *m_mutablePropertyVector = properties;
+ } else {
+ m_arraySize = properties.size();
+ for (unsigned i = 0; i < m_arraySize; ++i)
+ new (&array()[i]) CSSProperty(properties[i]);
+ }
}
StylePropertySet::StylePropertySet(const StylePropertySet& o)
: RefCounted<StylePropertySet>()
- , m_properties(o.m_properties)
, m_cssParserMode(o.m_cssParserMode)
, m_ownsCSSOMWrapper(false)
, m_isMutable(true)
+ , m_arraySize(0)
+ , m_mutablePropertyVector(new Vector<CSSProperty>)
{
+ copyPropertiesFrom(o);
}
StylePropertySet::~StylePropertySet()
@@ -82,6 +96,12 @@
ASSERT(!m_ownsCSSOMWrapper || propertySetCSSOMWrapperMap().contains(this));
if (m_ownsCSSOMWrapper)
propertySetCSSOMWrapperMap().remove(this);
+ if (isMutable())
+ delete m_mutablePropertyVector;
+ else {
+ for (unsigned i = 0; i < m_arraySize; ++i)
+ array()[i].~CSSProperty();
+ }
}
void StylePropertySet::setCSSParserMode(CSSParserMode cssParserMode)
@@ -93,7 +113,16 @@
void StylePropertySet::copyPropertiesFrom(const StylePropertySet& other)
{
ASSERT(isMutable());
- m_properties = other.m_properties;
+
+ if (other.isMutable()) {
+ *m_mutablePropertyVector = *other.m_mutablePropertyVector;
+ return;
+ }
+
+ ASSERT(m_mutablePropertyVector->isEmpty());
+ m_mutablePropertyVector->reserveInitialCapacity(other.m_arraySize);
+ for (unsigned i = 0; i < other.m_arraySize; ++i)
+ m_mutablePropertyVector->uncheckedAppend(other.array()[i]);
}
String StylePropertySet::getPropertyValue(CSSPropertyID propertyID) const
@@ -492,7 +521,7 @@
// A more efficient removal strategy would involve marking entries as empty
// and sweeping them when the vector grows too big.
- m_properties.remove(foundProperty - m_properties.data());
+ m_mutablePropertyVector->remove(foundProperty - m_mutablePropertyVector->data());
return true;
}
@@ -554,7 +583,7 @@
RefPtr<CSSValue> value = prpValue;
for (unsigned i = 0; i < shorthand.length(); ++i)
- m_properties.append(CSSProperty(shorthand.properties()[i], value, important));
+ append(CSSProperty(shorthand.properties()[i], value, important));
}
void StylePropertySet::setProperty(const CSSProperty& property, CSSProperty* slot)
@@ -567,7 +596,7 @@
return;
}
}
- m_properties.append(property);
+ append(property);
}
bool StylePropertySet::setProperty(CSSPropertyID propertyID, int identifier, bool important)
@@ -581,7 +610,7 @@
{
ASSERT(isMutable());
- m_properties.clear();
+ m_mutablePropertyVector->clear();
CSSParserContext context(cssParserMode());
if (contextStyleSheet) {
@@ -595,7 +624,7 @@
void StylePropertySet::addParsedProperties(const Vector<CSSProperty>& properties)
{
ASSERT(isMutable());
- m_properties.reserveCapacity(m_properties.size() + properties.size());
+ m_mutablePropertyVector->reserveCapacity(m_mutablePropertyVector->size() + properties.size());
for (unsigned i = 0; i < properties.size(); ++i)
addParsedProperty(properties[i]);
}
@@ -620,9 +649,9 @@
BitArray<numCSSProperties> shorthandPropertyUsed;
BitArray<numCSSProperties> shorthandPropertyAppeared;
- unsigned size = m_properties.size();
+ unsigned size = propertyCount();
for (unsigned n = 0; n < size; ++n) {
- const CSSProperty& prop = m_properties[n];
+ const CSSProperty& prop = propertyAt(n);
CSSPropertyID propertyID = prop.id();
CSSPropertyID shorthandPropertyID = CSSPropertyInvalid;
CSSPropertyID borderFallbackShorthandProperty = CSSPropertyInvalid;
@@ -833,24 +862,24 @@
void StylePropertySet::merge(const StylePropertySet* other, bool argOverridesOnConflict)
{
ASSERT(isMutable());
- unsigned size = other->m_properties.size();
+ unsigned size = other->propertyCount();
for (unsigned n = 0; n < size; ++n) {
- const CSSProperty& toMerge = other->m_properties[n];
+ const CSSProperty& toMerge = other->propertyAt(n);
CSSProperty* old = findPropertyWithId(toMerge.id());
if (old) {
if (!argOverridesOnConflict && old->value())
continue;
setProperty(toMerge, old);
} else
- m_properties.append(toMerge);
+ append(toMerge);
}
}
void StylePropertySet::addSubresourceStyleURLs(ListHashSet<KURL>& urls, StyleSheetContents* contextStyleSheet) const
{
- size_t size = m_properties.size();
- for (size_t i = 0; i < size; ++i)
- m_properties[i].value()->addSubresourceStyleURLs(urls, contextStyleSheet);
+ unsigned size = propertyCount();
+ for (unsigned i = 0; i < size; ++i)
+ propertyAt(i).value()->addSubresourceStyleURLs(urls, contextStyleSheet);
}
// This is the list of properties we want to copy in the copyBlockProperties() function.
@@ -896,7 +925,7 @@
bool StylePropertySet::removePropertiesInSet(const CSSPropertyID* set, unsigned length)
{
ASSERT(isMutable());
- if (m_properties.isEmpty())
+ if (m_mutablePropertyVector->isEmpty())
return false;
// FIXME: This is always used with static sets and in that case constructing the hash repeatedly is pretty pointless.
@@ -905,11 +934,11 @@
toRemove.add(set[i]);
StylePropertyVector newProperties;
- newProperties.reserveInitialCapacity(m_properties.size());
+ newProperties.reserveInitialCapacity(m_mutablePropertyVector->size());
- unsigned size = m_properties.size();
+ unsigned size = m_mutablePropertyVector->size();
for (unsigned n = 0; n < size; ++n) {
- const CSSProperty& property = m_properties[n];
+ const CSSProperty& property = m_mutablePropertyVector->at(n);
// Not quite sure if the isImportant test is needed but it matches the existing behavior.
if (!property.isImportant()) {
if (toRemove.contains(property.id()))
@@ -918,16 +947,16 @@
newProperties.append(property);
}
- bool changed = newProperties.size() != m_properties.size();
- m_properties = newProperties;
+ bool changed = newProperties.size() != m_mutablePropertyVector->size();
+ *m_mutablePropertyVector = newProperties;
return changed;
}
const CSSProperty* StylePropertySet::findPropertyWithId(CSSPropertyID propertyID) const
{
- for (int n = m_properties.size() - 1 ; n >= 0; --n) {
- if (propertyID == m_properties[n].id())
- return &m_properties[n];
+ for (int n = propertyCount() - 1 ; n >= 0; --n) {
+ if (propertyID == propertyAt(n).id())
+ return &propertyAt(n);
}
return 0;
}
@@ -935,9 +964,9 @@
CSSProperty* StylePropertySet::findPropertyWithId(CSSPropertyID propertyID)
{
ASSERT(isMutable());
- for (int n = m_properties.size() - 1 ; n >= 0; --n) {
- if (propertyID == m_properties[n].id())
- return &m_properties[n];
+ for (int n = propertyCount() - 1 ; n >= 0; --n) {
+ if (propertyID == propertyAt(n).id())
+ return &propertyAt(n);
}
return 0;
}
@@ -952,9 +981,9 @@
{
ASSERT(isMutable());
Vector<CSSPropertyID> propertiesToRemove;
- size_t size = m_properties.size();
- for (size_t i = 0; i < size; ++i) {
- const CSSProperty& property = m_properties[i];
+ unsigned size = m_mutablePropertyVector->size();
+ for (unsigned i = 0; i < size; ++i) {
+ const CSSProperty& property = m_mutablePropertyVector->at(i);
if (style->propertyMatches(&property))
propertiesToRemove.append(property.id());
}
@@ -967,9 +996,9 @@
{
ASSERT(isMutable());
Vector<CSSPropertyID> propertiesToRemove;
- size_t size = m_properties.size();
- for (size_t i = 0; i < size; ++i) {
- const CSSProperty& property = m_properties[i];
+ unsigned size = m_mutablePropertyVector->size();
+ for (unsigned i = 0; i < size; ++i) {
+ const CSSProperty& property = m_mutablePropertyVector->at(i);
if (style->cssPropertyMatches(&property))
propertiesToRemove.append(property.id());
}
@@ -992,7 +1021,7 @@
if (value)
list.append(CSSProperty(set[i], value.release(), false));
}
- return StylePropertySet::adoptMutable(list);
+ return StylePropertySet::create(list);
}
CSSStyleDeclaration* StylePropertySet::ensureCSSStyleDeclaration() const
@@ -1031,13 +1060,13 @@
unsigned StylePropertySet::averageSizeInBytes()
{
// Please update this if the storage scheme changes so that this longer reflects the actual size.
- return sizeof(StylePropertySet);
+ return sizeof(StylePropertySet) + sizeof(CSSProperty) * 2;
}
// See the function above if you need to update this.
class SameSizeAsStylePropertySet : public RefCounted<SameSizeAsStylePropertySet> {
- StylePropertyVector properties;
unsigned bitfield;
+ void* properties;
};
COMPILE_ASSERT(sizeof(StylePropertySet) == sizeof(SameSizeAsStylePropertySet), style_property_set_should_stay_small);
@@ -1048,4 +1077,10 @@
}
#endif
+inline void StylePropertySet::append(const CSSProperty& property)
+{
+ ASSERT(isMutable());
+ m_mutablePropertyVector->append(property);
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/css/StylePropertySet.h (118808 => 118809)
--- trunk/Source/WebCore/css/StylePropertySet.h 2012-05-29 18:15:03 UTC (rev 118808)
+++ trunk/Source/WebCore/css/StylePropertySet.h 2012-05-29 18:19:59 UTC (rev 118809)
@@ -49,23 +49,17 @@
{
return adoptRef(new StylePropertySet(cssParserMode));
}
- static PassRefPtr<StylePropertySet> adopt(StylePropertyVector& properties, CSSParserMode cssParserMode)
+ static PassRefPtr<StylePropertySet> create(StylePropertyVector& properties)
{
- return adoptRef(new StylePropertySet(properties, cssParserMode));
+ return adoptRef(new StylePropertySet(properties, CSSStrictMode, /* makeMutable */ true));
}
- static PassRefPtr<StylePropertySet> adoptMutable(StylePropertyVector& properties)
- {
- RefPtr<StylePropertySet> result = adoptRef(new StylePropertySet(properties, CSSStrictMode));
- result->m_isMutable = true;
- return result.release();
- }
+ static PassRefPtr<StylePropertySet> createImmutable(StylePropertyVector&, CSSParserMode);
- unsigned propertyCount() const { return m_properties.size(); }
- bool isEmpty() const { return m_properties.isEmpty(); }
- const CSSProperty& propertyAt(unsigned index) const { return m_properties[index]; }
+ unsigned propertyCount() const;
+ bool isEmpty() const;
+ const CSSProperty& propertyAt(unsigned index) const;
+ CSSProperty& propertyAt(unsigned index);
- void shrinkToFit() { m_properties.shrinkToFit(); }
-
PassRefPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const;
String getPropertyValue(CSSPropertyID) const;
bool propertyIsImportant(CSSPropertyID) const;
@@ -125,7 +119,7 @@
private:
StylePropertySet(CSSParserMode);
- StylePropertySet(StylePropertyVector&, CSSParserMode);
+ StylePropertySet(StylePropertyVector&, CSSParserMode, bool makeMutable);
StylePropertySet(const StylePropertySet&);
void setNeedsStyleRecalc();
@@ -146,15 +140,61 @@
const CSSProperty* findPropertyWithId(CSSPropertyID) const;
CSSProperty* findPropertyWithId(CSSPropertyID);
- StylePropertyVector m_properties;
+ void append(const CSSProperty&);
+ CSSProperty* array();
+ const CSSProperty* array() const;
unsigned m_cssParserMode : 2;
mutable unsigned m_ownsCSSOMWrapper : 1;
mutable unsigned m_isMutable : 1;
+ unsigned m_arraySize : 28;
+
+ union {
+ Vector<CSSProperty>* m_mutablePropertyVector;
+ void* m_properties;
+ };
friend class PropertySetCSSStyleDeclaration;
};
+inline CSSProperty& StylePropertySet::propertyAt(unsigned index)
+{
+ if (isMutable())
+ return m_mutablePropertyVector->at(index);
+ return array()[index];
+}
+
+inline const CSSProperty& StylePropertySet::propertyAt(unsigned index) const
+{
+ if (isMutable())
+ return m_mutablePropertyVector->at(index);
+ return array()[index];
+}
+
+inline unsigned StylePropertySet::propertyCount() const
+{
+ if (isMutable())
+ return m_mutablePropertyVector->size();
+ return m_arraySize;
+}
+
+inline bool StylePropertySet::isEmpty() const
+{
+ return !propertyCount();
+}
+
+inline CSSProperty* StylePropertySet::array()
+{
+ ASSERT(!isMutable());
+ return reinterpret_cast<CSSProperty*>(&m_properties);
+}
+
+inline const CSSProperty* StylePropertySet::array() const
+{
+ ASSERT(!isMutable());
+ return reinterpret_cast<const CSSProperty*>(&m_properties);
+}
+
} // namespace WebCore
#endif // StylePropertySet_h