Changeset 128109 in webkit
- Timestamp:
- Sep 10, 2012 2:43:52 PM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r128107 r128109 1 2012-09-10 Andreas Kling <kling@webkit.org> 2 3 ElementAttributeData: Use subclasses to manage varying object layouts. 4 <http://webkit.org/b/94465> 5 6 Reviewed by Antti Koivisto. 7 8 Add two ElementAttributeData subclasses: 9 10 - MutableElementAttributeData 11 - ImmutableElementAttributeData 12 13 The ElementAttributeData::m_isMutable bit determines which subclass to cast to when accessing 14 the attribute storage. Added mutableAttributeVector() and immutableAttributeArray() helpers 15 to ElementAttributeData (with appropriate assertions.) 16 17 This patch removes one step of indirection in the mutable case, since the Vector<Attribute> is no 18 longer heap-allocated, but part of MutableElementAttributeData. 19 20 Added a WTF::deleteOwnedPtr(ElementAttributeData*) specialization so that the appropriate subclass 21 destructor is called for these objects. 22 23 * WebCore.exp.in: 24 * dom/Element.cpp: 25 (WebCore::Element::createMutableAttributeData): 26 * dom/ElementAttributeData.cpp: 27 (WebCore::ElementAttributeData::createImmutable): 28 (WebCore::ElementAttributeData::create): 29 (WebCore::ElementAttributeData::ElementAttributeData): 30 (WebCore::MutableElementAttributeData::MutableElementAttributeData): 31 (WebCore::ImmutableElementAttributeData::ImmutableElementAttributeData): 32 (WebCore::ImmutableElementAttributeData::~ImmutableElementAttributeData): 33 (WebCore::ElementAttributeData::makeMutableCopy): 34 (WebCore::ElementAttributeData::addAttribute): 35 (WebCore::ElementAttributeData::removeAttribute): 36 (WebCore::ElementAttributeData::reportMemoryUsage): 37 (WebCore::ElementAttributeData::cloneDataFrom): 38 (WebCore::ElementAttributeData::clearAttributes): 39 * dom/ElementAttributeData.h: 40 (ElementAttributeData): 41 (WebCore::ElementAttributeData::isMutable): 42 (ImmutableElementAttributeData): 43 (MutableElementAttributeData): 44 (WebCore::MutableElementAttributeData::MutableElementAttributeData): 45 (WebCore::ElementAttributeData::immutableAttributeArray): 46 (WebCore::ElementAttributeData::mutableAttributeVector): 47 (WebCore::ElementAttributeData::length): 48 (WebCore::ElementAttributeData::attributeItem): 49 1 50 2012-09-10 Tony Chang <tony@chromium.org> 2 51 -
trunk/Source/WebCore/WebCore.exp.in
r127932 r128109 231 231 __ZN7WebCore13toHTMLElementEPNS_21FormAssociatedElementE 232 232 __ZN7WebCore13toJSDOMWindowEN3JSC7JSValueE 233 __ZN7WebCore13QualifiedNameD1Ev 233 234 __ZN7WebCore14CachedResource12removeClientEPNS_20CachedResourceClientE 234 235 __ZN7WebCore14CachedResource16unregisterHandleEPNS_24CachedResourceHandleBaseE … … 539 540 __ZN7WebCore20makeRGBA32FromFloatsEffff 540 541 __ZN7WebCore20protocolIsJavaScriptERKN3WTF6StringE 542 __ZN7WebCore20SpaceSplitStringDataD1Ev 541 543 __ZN7WebCore21BackForwardController11itemAtIndexEi 542 544 __ZN7WebCore21MemoryPressureHandler7installEv -
trunk/Source/WebCore/dom/Element.cpp
r128009 r128109 2247 2247 m_attributeData = ElementAttributeData::create(); 2248 2248 else 2249 m_attributeData = m_attributeData->makeMutable ();2249 m_attributeData = m_attributeData->makeMutableCopy(); 2250 2250 } 2251 2251 -
trunk/Source/WebCore/dom/ElementAttributeData.cpp
r127869 r128109 37 37 static size_t immutableElementAttributeDataSize(unsigned count) 38 38 { 39 return sizeof( ElementAttributeData) - sizeof(void*) + sizeof(Attribute) * count;39 return sizeof(ImmutableElementAttributeData) + sizeof(Attribute) * count; 40 40 } 41 41 … … 43 43 { 44 44 void* slot = WTF::fastMalloc(immutableElementAttributeDataSize(attributes.size())); 45 return adoptRef(new (slot) ElementAttributeData(attributes)); 46 } 47 48 ElementAttributeData::ElementAttributeData() 49 : m_isMutable(true) 50 , m_arraySize(0) 51 , m_mutableAttributeVector(new Vector<Attribute, 4>) 52 { 53 } 54 55 ElementAttributeData::ElementAttributeData(const Vector<Attribute>& attributes) 56 : m_isMutable(false) 57 , m_arraySize(attributes.size()) 58 { 59 Attribute* buffer = reinterpret_cast<Attribute*>(&m_attributes); 60 for (unsigned i = 0; i < attributes.size(); ++i) 61 new (&buffer[i]) Attribute(attributes[i]); 62 } 63 64 ElementAttributeData::ElementAttributeData(const ElementAttributeData& other) 65 : RefCounted<ElementAttributeData>() 66 , m_isMutable(true) 67 , m_arraySize(0) 68 , m_inlineStyleDecl(other.m_inlineStyleDecl) 69 , m_attributeStyle(other.m_attributeStyle) 70 , m_classNames(other.m_classNames) 71 , m_idForStyleResolution(other.m_idForStyleResolution) 72 , m_mutableAttributeVector(new Vector<Attribute, 4>) 73 { 74 // This copy constructor should only be used by makeMutable() to go from immutable to mutable. 75 ASSERT(!other.m_isMutable); 76 77 // An immutable ElementAttributeData should never have a mutable inline StylePropertySet attached. 78 ASSERT(!other.m_inlineStyleDecl || !other.m_inlineStyleDecl->isMutable()); 79 80 const Attribute* otherBuffer = reinterpret_cast<const Attribute*>(&other.m_attributes); 81 for (unsigned i = 0; i < other.m_arraySize; ++i) 82 m_mutableAttributeVector->append(otherBuffer[i]); 83 } 84 85 ElementAttributeData::~ElementAttributeData() 86 { 87 if (isMutable()) { 88 ASSERT(!m_arraySize); 89 delete m_mutableAttributeVector; 90 } else { 91 Attribute* buffer = reinterpret_cast<Attribute*>(&m_attributes); 92 for (unsigned i = 0; i < m_arraySize; ++i) 93 buffer[i].~Attribute(); 94 } 45 return adoptRef(new (slot) ImmutableElementAttributeData(attributes)); 46 } 47 48 PassRefPtr<ElementAttributeData> ElementAttributeData::create() 49 { 50 return adoptRef(new MutableElementAttributeData); 51 } 52 53 ImmutableElementAttributeData::ImmutableElementAttributeData(const Vector<Attribute>& attributes) 54 : ElementAttributeData(attributes.size()) 55 { 56 for (unsigned i = 0; i < m_arraySize; ++i) 57 new (&m_attributeArray[i]) Attribute(attributes[i]); 58 } 59 60 MutableElementAttributeData::MutableElementAttributeData(const ImmutableElementAttributeData& other) 61 { 62 const ElementAttributeData& baseOther = static_cast<const ElementAttributeData&>(other); 63 64 m_inlineStyleDecl = baseOther.m_inlineStyleDecl; 65 m_attributeStyle = baseOther.m_attributeStyle; 66 m_classNames = baseOther.m_classNames; 67 m_idForStyleResolution = baseOther.m_idForStyleResolution; 68 69 // An ImmutableElementAttributeData should never have a mutable inline StylePropertySet attached. 70 ASSERT(!baseOther.m_inlineStyleDecl || !baseOther.m_inlineStyleDecl->isMutable()); 71 72 m_attributeVector.reserveCapacity(baseOther.m_arraySize); 73 for (unsigned i = 0; i < baseOther.m_arraySize; ++i) 74 m_attributeVector.uncheckedAppend(other.m_attributeArray[i]); 75 } 76 77 ImmutableElementAttributeData::~ImmutableElementAttributeData() 78 { 79 for (unsigned i = 0; i < m_arraySize; ++i) 80 m_attributeArray[i].~Attribute(); 81 } 82 83 PassRefPtr<ElementAttributeData> ElementAttributeData::makeMutableCopy() const 84 { 85 ASSERT(!isMutable()); 86 return adoptRef(new MutableElementAttributeData(static_cast<const ImmutableElementAttributeData&>(*this))); 95 87 } 96 88 … … 237 229 element->willModifyAttribute(attribute.name(), nullAtom, attribute.value()); 238 230 239 m _mutableAttributeVector->append(attribute);231 mutableAttributeVector().append(attribute); 240 232 241 233 if (element && inSynchronizationOfLazyAttribute == NotInSynchronizationOfLazyAttribute) … … 248 240 ASSERT(index < length()); 249 241 250 Attribute& attribute = m _mutableAttributeVector->at(index);242 Attribute& attribute = mutableAttributeVector().at(index); 251 243 QualifiedName name = attribute.name(); 252 244 … … 257 249 attr->detachFromElementWithValue(attribute.value()); 258 250 259 m _mutableAttributeVector->remove(index);251 mutableAttributeVector().remove(index); 260 252 261 253 if (element && inSynchronizationOfLazyAttribute == NotInSynchronizationOfLazyAttribute) … … 305 297 info.addInstrumentedMember(m_idForStyleResolution); 306 298 if (m_isMutable) 307 info.addVector Ptr(m_mutableAttributeVector);299 info.addVector(mutableAttributeVector()); 308 300 for (unsigned i = 0, len = length(); i < len; i++) 309 301 info.addInstrumentedMember(*attributeItem(i)); … … 349 341 350 342 if (sourceData.isMutable()) 351 *m_mutableAttributeVector = *sourceData.m_mutableAttributeVector;343 mutableAttributeVector() = sourceData.mutableAttributeVector(); 352 344 else { 353 ASSERT(m_mutableAttributeVector->isEmpty()); 354 m_mutableAttributeVector->reserveInitialCapacity(sourceData.m_arraySize); 355 const Attribute* sourceBuffer = reinterpret_cast<const Attribute*>(&sourceData.m_attributes); 345 mutableAttributeVector().reserveInitialCapacity(sourceData.m_arraySize); 356 346 for (unsigned i = 0; i < sourceData.m_arraySize; ++i) 357 m _mutableAttributeVector->uncheckedAppend(sourceBuffer[i]);347 mutableAttributeVector().uncheckedAppend(sourceData.immutableAttributeArray()[i]); 358 348 } 359 349 360 350 for (unsigned i = 0; i < length(); ++i) { 361 const Attribute& attribute = m _mutableAttributeVector->at(i);351 const Attribute& attribute = mutableAttributeVector().at(i); 362 352 if (targetElement.isStyledElement() && attribute.name() == HTMLNames::styleAttr) { 363 353 static_cast<StyledElement&>(targetElement).styleAttributeChanged(attribute.value(), StyledElement::DoNotReparseStyleAttribute); … … 381 371 382 372 clearClass(); 383 m _mutableAttributeVector->clear();373 mutableAttributeVector().clear(); 384 374 } 385 375 -
trunk/Source/WebCore/dom/ElementAttributeData.h
r127438 r128109 36 36 class Attr; 37 37 class Element; 38 class ImmutableElementAttributeData; 38 39 class MemoryObjectInfo; 40 class MutableElementAttributeData; 39 41 40 42 enum SynchronizationOfLazyAttribute { NotInSynchronizationOfLazyAttribute, InSynchronizationOfLazyAttribute }; … … 43 45 WTF_MAKE_FAST_ALLOCATED; 44 46 public: 45 static PassRefPtr<ElementAttributeData> create() { return adoptRef(new ElementAttributeData); }47 static PassRefPtr<ElementAttributeData> create(); 46 48 static PassRefPtr<ElementAttributeData> createImmutable(const Vector<Attribute>&); 47 ~ElementAttributeData();48 49 49 50 void clearClass() { m_classNames.clear(); } … … 96 97 void reportMemoryUsage(MemoryObjectInfo*) const; 97 98 99 bool isMutable() const { return m_isMutable; } 100 101 protected: 102 ElementAttributeData() 103 : m_isMutable(true) 104 , m_arraySize(0) 105 { } 106 107 ElementAttributeData(unsigned arraySize) 108 : m_isMutable(false) 109 , m_arraySize(arraySize) 110 { } 111 112 mutable RefPtr<StylePropertySet> m_inlineStyleDecl; 113 mutable RefPtr<StylePropertySet> m_attributeStyle; 114 mutable SpaceSplitString m_classNames; 115 mutable AtomicString m_idForStyleResolution; 116 117 unsigned m_isMutable : 1; 118 unsigned m_arraySize : 31; 119 98 120 private: 99 121 friend class Element; 100 122 friend class HTMLConstructionSite; 101 102 ElementAttributeData(); 103 ElementAttributeData(const ElementAttributeData&); 104 ElementAttributeData(const Vector<Attribute>&); 123 friend class ImmutableElementAttributeData; 124 friend class MutableElementAttributeData; 105 125 106 126 Attribute* getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase); … … 110 130 void clearAttributes(Element*); 111 131 112 bool isMutable() const { return m_isMutable; } 113 PassRefPtr<ElementAttributeData> makeMutable() const { return adoptRef(new ElementAttributeData(*this)); } 114 115 unsigned m_isMutable : 1; 116 unsigned m_arraySize : 31; 117 118 mutable RefPtr<StylePropertySet> m_inlineStyleDecl; 119 mutable RefPtr<StylePropertySet> m_attributeStyle; 120 mutable SpaceSplitString m_classNames; 121 mutable AtomicString m_idForStyleResolution; 122 123 union { 124 Vector<Attribute, 4>* m_mutableAttributeVector; 125 void* m_attributes; 126 }; 132 PassRefPtr<ElementAttributeData> makeMutableCopy() const; 133 134 Vector<Attribute, 4>& mutableAttributeVector(); 135 const Vector<Attribute, 4>& mutableAttributeVector() const; 136 const Attribute* immutableAttributeArray() const; 127 137 }; 128 138 139 class ImmutableElementAttributeData : public ElementAttributeData { 140 public: 141 ImmutableElementAttributeData(const Vector<Attribute>&); 142 ~ImmutableElementAttributeData(); 143 144 Attribute m_attributeArray[0]; 145 }; 146 147 class MutableElementAttributeData : public ElementAttributeData { 148 public: 149 MutableElementAttributeData() { } 150 MutableElementAttributeData(const ImmutableElementAttributeData&); 151 152 Vector<Attribute, 4> m_attributeVector; 153 }; 154 155 inline Vector<Attribute, 4>& ElementAttributeData::mutableAttributeVector() 156 { 157 ASSERT(m_isMutable); 158 return static_cast<MutableElementAttributeData*>(this)->m_attributeVector; 159 } 160 161 inline const Vector<Attribute, 4>& ElementAttributeData::mutableAttributeVector() const 162 { 163 ASSERT(m_isMutable); 164 return static_cast<const MutableElementAttributeData*>(this)->m_attributeVector; 165 } 166 167 inline const Attribute* ElementAttributeData::immutableAttributeArray() const 168 { 169 ASSERT(!m_isMutable); 170 return static_cast<const ImmutableElementAttributeData*>(this)->m_attributeArray; 171 } 172 129 173 inline size_t ElementAttributeData::length() const 130 174 { 131 175 if (isMutable()) 132 return m _mutableAttributeVector->size();176 return mutableAttributeVector().size(); 133 177 return m_arraySize; 134 178 } … … 202 246 { 203 247 ASSERT(index < length()); 204 if (isMutable()) 205 return &m_mutableAttributeVector->at(index); 206 const Attribute* buffer = reinterpret_cast<const Attribute*>(&m_attributes); 207 return &buffer[index]; 248 if (m_isMutable) 249 return &mutableAttributeVector().at(index); 250 return &immutableAttributeArray()[index]; 208 251 } 209 252 210 253 inline Attribute* ElementAttributeData::attributeItem(unsigned index) 211 254 { 212 ASSERT(isMutable());213 255 ASSERT(index < length()); 214 return &m_mutableAttributeVector->at(index); 256 return &mutableAttributeVector().at(index); 257 } 258 259 } 260 261 namespace WTF { 262 263 template <> inline void deleteOwnedPtr<WebCore::ElementAttributeData>(WebCore::ElementAttributeData* ptr) 264 { 265 if (!ptr) 266 return; 267 if (ptr->isMutable()) 268 delete static_cast<WebCore::MutableElementAttributeData*>(ptr); 269 else 270 delete static_cast<WebCore::ImmutableElementAttributeData*>(ptr); 215 271 } 216 272
Note: See TracChangeset
for help on using the changeset viewer.