Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * Copyright (C) 2014 Apple Inc. All rights reserved. | 3 * Copyright (C) 2014 Apple Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 */ | 30 */ |
| 31 | 31 |
| 32 #ifndef ElementData_h | 32 #ifndef ElementData_h |
| 33 #define ElementData_h | 33 #define ElementData_h |
| 34 | 34 |
| 35 #include "core/dom/Attribute.h" | 35 #include "core/dom/Attribute.h" |
| 36 #include "core/dom/SpaceSplitString.h" | 36 #include "core/dom/SpaceSplitString.h" |
| 37 #include "platform/heap/Handle.h" | |
| 37 #include "wtf/text/AtomicString.h" | 38 #include "wtf/text/AtomicString.h" |
| 38 | 39 |
| 39 namespace WebCore { | 40 namespace WebCore { |
| 40 | 41 |
| 41 class Attr; | 42 class Attr; |
| 42 class ShareableElementData; | 43 class ShareableElementData; |
| 43 class StylePropertySet; | 44 class StylePropertySet; |
| 44 class UniqueElementData; | 45 class UniqueElementData; |
| 45 | 46 |
| 46 class AttributeCollection { | 47 class AttributeCollection { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 57 | 58 |
| 58 unsigned size() const { return m_size; } | 59 unsigned size() const { return m_size; } |
| 59 | 60 |
| 60 private: | 61 private: |
| 61 const Attribute* m_array; | 62 const Attribute* m_array; |
| 62 unsigned m_size; | 63 unsigned m_size; |
| 63 }; | 64 }; |
| 64 | 65 |
| 65 // ElementData represents very common, but not necessarily unique to an element, | 66 // ElementData represents very common, but not necessarily unique to an element, |
| 66 // data such as attributes, inline style, and parsed class names and ids. | 67 // data such as attributes, inline style, and parsed class names and ids. |
| 67 class ElementData : public RefCounted<ElementData> { | 68 class ElementData : public RefCountedWillBeGarbageCollectedFinalized<ElementData > { |
| 68 WTF_MAKE_FAST_ALLOCATED; | 69 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED; |
| 69 public: | 70 public: |
| 71 #if ENABLE(OILPAN) | |
| 72 // Override GarbageCollectedFinalized's finalizeGarbageCollectedObject to | |
| 73 // dispatch to the correct subclass' destructor. | |
|
Mads Ager (chromium)
2014/06/25 09:18:33
Nit: subclass's destructor or subclass destructor
wibling-chromium
2014/06/25 09:30:47
I tend not to add an extra s when the word is endi
| |
| 74 void finalizeGarbageCollectedObject(); | |
| 75 #else | |
| 70 // Override RefCounted's deref() to ensure operator delete is called on | 76 // Override RefCounted's deref() to ensure operator delete is called on |
| 71 // the appropriate subclass type. | 77 // the appropriate subclass type. |
| 72 void deref(); | 78 void deref(); |
| 79 #endif | |
| 73 | 80 |
| 74 void clearClass() const { m_classNames.clear(); } | 81 void clearClass() const { m_classNames.clear(); } |
| 75 void setClass(const AtomicString& className, bool shouldFoldCase) const { m_ classNames.set(className, shouldFoldCase); } | 82 void setClass(const AtomicString& className, bool shouldFoldCase) const { m_ classNames.set(className, shouldFoldCase); } |
| 76 const SpaceSplitString& classNames() const { return m_classNames; } | 83 const SpaceSplitString& classNames() const { return m_classNames; } |
| 77 | 84 |
| 78 const AtomicString& idForStyleResolution() const { return m_idForStyleResolu tion; } | 85 const AtomicString& idForStyleResolution() const { return m_idForStyleResolu tion; } |
| 79 void setIdForStyleResolution(const AtomicString& newId) const { m_idForStyle Resolution = newId; } | 86 void setIdForStyleResolution(const AtomicString& newId) const { m_idForStyle Resolution = newId; } |
| 80 | 87 |
| 81 const StylePropertySet* inlineStyle() const { return m_inlineStyle.get(); } | 88 const StylePropertySet* inlineStyle() const { return m_inlineStyle.get(); } |
| 82 | 89 |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 94 size_t findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreA ttributeCase) const; | 101 size_t findAttributeIndexByName(const AtomicString& name, bool shouldIgnoreA ttributeCase) const; |
| 95 size_t findAttrNodeIndex(Attr*) const; | 102 size_t findAttrNodeIndex(Attr*) const; |
| 96 | 103 |
| 97 bool hasID() const { return !m_idForStyleResolution.isNull(); } | 104 bool hasID() const { return !m_idForStyleResolution.isNull(); } |
| 98 bool hasClass() const { return !m_classNames.isNull(); } | 105 bool hasClass() const { return !m_classNames.isNull(); } |
| 99 | 106 |
| 100 bool isEquivalent(const ElementData* other) const; | 107 bool isEquivalent(const ElementData* other) const; |
| 101 | 108 |
| 102 bool isUnique() const { return m_isUnique; } | 109 bool isUnique() const { return m_isUnique; } |
| 103 | 110 |
| 111 void traceAfterDispatch(Visitor*); | |
| 112 void trace(Visitor*); | |
| 113 | |
| 104 protected: | 114 protected: |
| 105 ElementData(); | 115 ElementData(); |
| 106 explicit ElementData(unsigned arraySize); | 116 explicit ElementData(unsigned arraySize); |
| 107 ElementData(const ElementData&, bool isUnique); | 117 ElementData(const ElementData&, bool isUnique); |
| 108 | 118 |
| 109 // Keep the type in a bitfield instead of using virtual destructors to avoid adding a vtable. | 119 // Keep the type in a bitfield instead of using virtual destructors to avoid adding a vtable. |
| 110 unsigned m_isUnique : 1; | 120 unsigned m_isUnique : 1; |
| 111 unsigned m_arraySize : 28; | 121 unsigned m_arraySize : 28; |
| 112 mutable unsigned m_presentationAttributeStyleIsDirty : 1; | 122 mutable unsigned m_presentationAttributeStyleIsDirty : 1; |
| 113 mutable unsigned m_styleAttributeIsDirty : 1; | 123 mutable unsigned m_styleAttributeIsDirty : 1; |
| 114 mutable unsigned m_animatedSVGAttributesAreDirty : 1; | 124 mutable unsigned m_animatedSVGAttributesAreDirty : 1; |
| 115 | 125 |
| 116 mutable RefPtr<StylePropertySet> m_inlineStyle; | 126 mutable RefPtrWillBeMember<StylePropertySet> m_inlineStyle; |
| 117 mutable SpaceSplitString m_classNames; | 127 mutable SpaceSplitString m_classNames; |
| 118 mutable AtomicString m_idForStyleResolution; | 128 mutable AtomicString m_idForStyleResolution; |
| 119 | 129 |
| 120 private: | 130 private: |
| 121 friend class Element; | 131 friend class Element; |
| 122 friend class ShareableElementData; | 132 friend class ShareableElementData; |
| 123 friend class UniqueElementData; | 133 friend class UniqueElementData; |
| 124 friend class SVGElement; | 134 friend class SVGElement; |
| 125 | 135 |
| 136 #if !ENABLE(OILPAN) | |
| 126 void destroy(); | 137 void destroy(); |
| 138 #endif | |
| 127 | 139 |
| 128 const Attribute* attributeBase() const; | 140 const Attribute* attributeBase() const; |
| 129 const Attribute* findAttributeByName(const AtomicString& name, bool shouldIg noreAttributeCase) const; | 141 const Attribute* findAttributeByName(const AtomicString& name, bool shouldIg noreAttributeCase) const; |
| 130 size_t findAttributeIndexByNameSlowCase(const AtomicString& name, bool shoul dIgnoreAttributeCase) const; | 142 size_t findAttributeIndexByNameSlowCase(const AtomicString& name, bool shoul dIgnoreAttributeCase) const; |
| 131 | 143 |
| 132 PassRefPtr<UniqueElementData> makeUniqueCopy() const; | 144 PassRefPtrWillBeRawPtr<UniqueElementData> makeUniqueCopy() const; |
| 133 }; | 145 }; |
| 134 | 146 |
| 135 #if COMPILER(MSVC) | 147 #if COMPILER(MSVC) |
| 136 #pragma warning(push) | 148 #pragma warning(push) |
| 137 #pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" war ning | 149 #pragma warning(disable: 4200) // Disable "zero-sized array in struct/union" war ning |
| 138 #endif | 150 #endif |
| 139 | 151 |
| 140 // SharableElementData is managed by ElementDataCache and is produced by | 152 // SharableElementData is managed by ElementDataCache and is produced by |
| 141 // the parser during page load for elements that have identical attributes. This | 153 // the parser during page load for elements that have identical attributes. This |
| 142 // is a memory optimization since it's very common for many elements to have | 154 // is a memory optimization since it's very common for many elements to have |
| 143 // duplicate sets of attributes (ex. the same classes). | 155 // duplicate sets of attributes (ex. the same classes). |
| 144 class ShareableElementData FINAL : public ElementData { | 156 class ShareableElementData FINAL : public ElementData { |
| 145 public: | 157 public: |
| 146 static PassRefPtr<ShareableElementData> createWithAttributes(const Vector<At tribute>&); | 158 static PassRefPtrWillBeRawPtr<ShareableElementData> createWithAttributes(con st Vector<Attribute>&); |
| 147 | 159 |
| 148 explicit ShareableElementData(const Vector<Attribute>&); | 160 explicit ShareableElementData(const Vector<Attribute>&); |
| 149 explicit ShareableElementData(const UniqueElementData&); | 161 explicit ShareableElementData(const UniqueElementData&); |
| 150 ~ShareableElementData(); | 162 ~ShareableElementData(); |
| 151 | 163 |
| 164 void traceAfterDispatch(Visitor* visitor) { ElementData::traceAfterDispatch( visitor); } | |
| 165 | |
| 166 // Add support for placement new as ShareableElementData is not allocated | |
| 167 // with a fixed size. Instead the allocated memory size is computed based on | |
| 168 // the number of attributes. This requires us to use Heap::allocate directly | |
| 169 // with the computed size and subsequently call placement new with the | |
| 170 // allocated memory address. | |
| 171 void* operator new(std::size_t, void* location) | |
| 172 { | |
| 173 return location; | |
| 174 } | |
| 175 | |
| 152 Attribute m_attributeArray[0]; | 176 Attribute m_attributeArray[0]; |
| 153 }; | 177 }; |
| 154 | 178 |
| 155 #if COMPILER(MSVC) | 179 #if COMPILER(MSVC) |
| 156 #pragma warning(pop) | 180 #pragma warning(pop) |
| 157 #endif | 181 #endif |
| 158 | 182 |
| 159 // UniqueElementData is created when an element needs to mutate its attributes | 183 // UniqueElementData is created when an element needs to mutate its attributes |
| 160 // or gains presentation attribute style (ex. width="10"). It does not need to | 184 // or gains presentation attribute style (ex. width="10"). It does not need to |
| 161 // be created to fill in values in the ElementData that are derived from | 185 // be created to fill in values in the ElementData that are derived from |
| 162 // attributes. For example populating the m_inlineStyle from the style attribute | 186 // attributes. For example populating the m_inlineStyle from the style attribute |
| 163 // doesn't require a UniqueElementData as all elements with the same style | 187 // doesn't require a UniqueElementData as all elements with the same style |
| 164 // attribute will have the same inline style. | 188 // attribute will have the same inline style. |
| 165 class UniqueElementData FINAL : public ElementData { | 189 class UniqueElementData FINAL : public ElementData { |
| 166 public: | 190 public: |
| 167 static PassRefPtr<UniqueElementData> create(); | 191 static PassRefPtrWillBeRawPtr<UniqueElementData> create(); |
| 168 PassRefPtr<ShareableElementData> makeShareableCopy() const; | 192 PassRefPtrWillBeRawPtr<ShareableElementData> makeShareableCopy() const; |
| 169 | 193 |
| 170 // These functions do no error/duplicate checking. | 194 // These functions do no error/duplicate checking. |
| 171 void appendAttribute(const QualifiedName&, const AtomicString&); | 195 void appendAttribute(const QualifiedName&, const AtomicString&); |
| 172 void removeAttributeAt(size_t index); | 196 void removeAttributeAt(size_t index); |
| 173 | 197 |
| 174 Attribute& attributeAt(unsigned index); | 198 Attribute& attributeAt(unsigned index); |
| 175 Attribute* findAttributeByName(const QualifiedName&); | 199 Attribute* findAttributeByName(const QualifiedName&); |
| 176 | 200 |
| 177 UniqueElementData(); | 201 UniqueElementData(); |
| 178 explicit UniqueElementData(const ShareableElementData&); | 202 explicit UniqueElementData(const ShareableElementData&); |
| 179 explicit UniqueElementData(const UniqueElementData&); | 203 explicit UniqueElementData(const UniqueElementData&); |
| 180 | 204 |
| 205 void traceAfterDispatch(Visitor*); | |
| 206 | |
| 181 // FIXME: We might want to support sharing element data for elements with | 207 // FIXME: We might want to support sharing element data for elements with |
| 182 // presentation attribute style. Lots of table cells likely have the same | 208 // presentation attribute style. Lots of table cells likely have the same |
| 183 // attributes. Most modern pages don't use presentation attributes though | 209 // attributes. Most modern pages don't use presentation attributes though |
| 184 // so this might not make sense. | 210 // so this might not make sense. |
| 185 mutable RefPtr<StylePropertySet> m_presentationAttributeStyle; | 211 mutable RefPtrWillBeMember<StylePropertySet> m_presentationAttributeStyle; |
| 186 Vector<Attribute, 4> m_attributeVector; | 212 Vector<Attribute, 4> m_attributeVector; |
| 187 }; | 213 }; |
| 188 | 214 |
| 215 #if !ENABLE(OILPAN) | |
| 189 inline void ElementData::deref() | 216 inline void ElementData::deref() |
| 190 { | 217 { |
| 191 if (!derefBase()) | 218 if (!derefBase()) |
| 192 return; | 219 return; |
| 193 destroy(); | 220 destroy(); |
| 194 } | 221 } |
| 222 #endif | |
| 195 | 223 |
| 196 inline size_t ElementData::attributeCount() const | 224 inline size_t ElementData::attributeCount() const |
| 197 { | 225 { |
| 198 if (isUnique()) | 226 if (isUnique()) |
| 199 return static_cast<const UniqueElementData*>(this)->m_attributeVector.si ze(); | 227 return static_cast<const UniqueElementData*>(this)->m_attributeVector.si ze(); |
| 200 return m_arraySize; | 228 return m_arraySize; |
| 201 } | 229 } |
| 202 | 230 |
| 203 inline const StylePropertySet* ElementData::presentationAttributeStyle() const | 231 inline const StylePropertySet* ElementData::presentationAttributeStyle() const |
| 204 { | 232 { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 298 } | 326 } |
| 299 | 327 |
| 300 inline Attribute& UniqueElementData::attributeAt(unsigned index) | 328 inline Attribute& UniqueElementData::attributeAt(unsigned index) |
| 301 { | 329 { |
| 302 return m_attributeVector.at(index); | 330 return m_attributeVector.at(index); |
| 303 } | 331 } |
| 304 | 332 |
| 305 } // namespace WebCore | 333 } // namespace WebCore |
| 306 | 334 |
| 307 #endif // ElementData_h | 335 #endif // ElementData_h |
| OLD | NEW |