Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Side by Side Diff: Source/core/css/CSSValue.h

Issue 1164573002: CSSValue Immediates: Change CSSValue to an object instead of a pointer (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebase Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/core/css/CSSUnsetValue.h ('k') | Source/core/css/CSSValue.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * (C) 1999-2003 Lars Knoll (knoll@kde.org) 2 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details. 13 * Library General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU Library General Public License 15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to 16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA. 18 * Boston, MA 02110-1301, USA.
19 */ 19 */
20 20
21 #ifndef CSSValue_h 21 #ifndef CSSValue_h
22 #define CSSValue_h 22 #define CSSValue_h
23 23
24 #include "core/CoreExport.h" 24 #include "core/CoreExport.h"
25 #include "core/css/CSSValueObject.h"
25 #include "platform/heap/Handle.h" 26 #include "platform/heap/Handle.h"
26 #include "platform/weborigin/KURL.h"
27 #include "wtf/HashMap.h"
28 #include "wtf/ListHashSet.h"
29 #include "wtf/RefCounted.h" 27 #include "wtf/RefCounted.h"
30 #include "wtf/RefPtr.h" 28 #include "wtf/RefPtr.h"
31 29
32 namespace blink { 30 namespace blink {
33 31
34 class CORE_EXPORT CSSValue : public RefCountedWillBeGarbageCollectedFinalized<CS SValue> { 32 // A non-nullable container for CSSValueObject. Takes ownership of the passed
33 // CSSValueObject.
34 class CORE_EXPORT CSSValue {
35 ALLOW_ONLY_INLINE_ALLOCATION();
36 friend class NullableCSSValue;
35 public: 37 public:
36 #if ENABLE(OILPAN) 38 // Not explicit to allow for casting.
37 // Override operator new to allocate CSSValue subtype objects onto 39 CSSValue(const CSSValueObject& cssValueObject)
38 // a dedicated heap. 40 : m_data(const_cast<CSSValueObject*>(&cssValueObject))
39 GC_PLUGIN_IGNORE("crbug.com/443854") 41 {
40 void* operator new(size_t size) 42 ASSERT(m_data);
41 { 43 ref();
42 return allocateObject(size, false); 44 }
43 } 45
44 static void* allocateObject(size_t size, bool isEager) 46 // TODO(sashab): Remove these; construction should only be available with
45 { 47 // CSSValueObject&.
46 ThreadState* state = ThreadStateFor<ThreadingTrait<CSSValue>::Affinity>: :state(); 48 template<class T> CSSValue(PassRefPtrWillBeRawPtr<T> cssValueObject)
47 return Heap::allocateOnHeapIndex(state, size, isEager ? ThreadState::Eag erSweepHeapIndex : ThreadState::CSSValueHeapIndex, GCInfoTrait<CSSValue>::index( )); 49 : m_data(cssValueObject.leakRef())
48 } 50 {
49 #else 51 static_assert(WTF::IsSubclass<T, CSSValueObject>::value, "Parameter must be a container for CSSValueObject");
50 // Override RefCounted's deref() to ensure operator delete is called on 52 ASSERT(m_data);
51 // the appropriate subclass type. 53 }
52 void deref() 54
53 { 55 #if !ENABLE(OILPAN)
54 if (derefBase()) 56 template<class T> CSSValue(RefPtrWillBeRawPtr<T> cssValueObject)
55 destroy(); 57 : m_data(cssValueObject.release().leakRef())
56 } 58 {
57 #endif // !ENABLE(OILPAN) 59 static_assert(WTF::IsSubclass<T, CSSValueObject>::value, "Parameter must be a container for CSSValueObject");
58 60 ASSERT(m_data);
59 String cssText() const; 61 }
60 62 #endif
61 bool isPrimitiveValue() const { return m_classType == PrimitiveClass; } 63
62 bool isValueList() const { return m_classType >= ValueListClass; } 64 CSSValue(const CSSValue& cssValue)
63 65 : m_data(cssValue.m_data)
64 bool isBaseValueList() const { return m_classType == ValueListClass; } 66 {
65 67 ref();
66 bool isBorderImageSliceValue() const { return m_classType == BorderImageSlic eClass; } 68 }
67 bool isCanvasValue() const { return m_classType == CanvasClass; } 69
68 bool isCursorImageValue() const { return m_classType == CursorImageClass; } 70 ~CSSValue()
69 bool isCrossfadeValue() const { return m_classType == CrossfadeClass; } 71 {
70 bool isFontFeatureValue() const { return m_classType == FontFeatureClass; } 72 deref();
71 bool isFontFaceSrcValue() const { return m_classType == FontFaceSrcClass; } 73 }
72 bool isFunctionValue() const { return m_classType == FunctionClass; } 74
73 bool isImageGeneratorValue() const { return m_classType >= CanvasClass && m_ classType <= RadialGradientClass; } 75 CSSValue& operator=(const CSSValue& rhs)
74 bool isGradientValue() const { return m_classType >= LinearGradientClass && m_classType <= RadialGradientClass; } 76 {
75 bool isImageSetValue() const { return m_classType == ImageSetClass; } 77 rhs.ref();
76 bool isImageValue() const { return m_classType == ImageClass; } 78 deref();
77 bool isImplicitInitialValue() const; 79 m_data = rhs.m_data;
78 bool isInheritedValue() const { return m_classType == InheritedClass; } 80 return *this;
79 bool isInitialValue() const { return m_classType == InitialClass; } 81 }
80 bool isUnsetValue() const { return m_classType == UnsetClass; } 82
81 bool isCSSWideKeyword() const { return m_classType >= InheritedClass && m_cl assType <= UnsetClass; } 83 bool operator==(const CSSValue& other) const
82 bool isLinearGradientValue() const { return m_classType == LinearGradientCla ss; } 84 {
83 bool isPathValue() const { return m_classType == PathClass; } 85 return m_data->equals(*other.m_data);
84 bool isRadialGradientValue() const { return m_classType == RadialGradientCla ss; } 86 }
85 bool isReflectValue() const { return m_classType == ReflectClass; } 87
86 bool isShadowValue() const { return m_classType == ShadowClass; } 88 // TODO: Remove this and update callsites to use operator== instead.
87 bool isCubicBezierTimingFunctionValue() const { return m_classType == CubicB ezierTimingFunctionClass; } 89 bool equals(const CSSValue& other) const
88 bool isStepsTimingFunctionValue() const { return m_classType == StepsTimingF unctionClass; } 90 {
89 bool isLineBoxContainValue() const { return m_classType == LineBoxContainCla ss; } 91 return m_data->equals(*other.m_data);
90 bool isCalcValue() const {return m_classType == CalculationClass; } 92 }
91 bool isGridTemplateAreasValue() const { return m_classType == GridTemplateAr easClass; } 93
92 bool isSVGDocumentValue() const { return m_classType == CSSSVGDocumentClass; } 94 bool ptrEquals(const CSSValue& other) const
93 bool isContentDistributionValue() const { return m_classType == CSSContentDi stributionClass; } 95 {
94 bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; } 96 return m_data == other.m_data;
95 bool isGridLineNamesValue() const { return m_classType == GridLineNamesClass ; } 97 }
96 98
97 bool hasFailedOrCanceledSubresources() const; 99 // Methods that proxy to CSSValueObject.
98 100 String cssText() const { return m_data->cssText(); }
99 bool equals(const CSSValue&) const; 101 bool hasFailedOrCanceledSubresources() const { return m_data->hasFailedOrCan celedSubresources(); };
100 102 bool isPrimitiveValue() const { return m_data->isPrimitiveValue(); }
101 void finalizeGarbageCollectedObject(); 103 bool isValueList() const { return m_data->isValueList(); }
102 DEFINE_INLINE_TRACE_AFTER_DISPATCH() { } 104 bool isBaseValueList() const { return m_data->isBaseValueList(); }
103 DECLARE_TRACE(); 105 bool isBorderImageSliceValue() const { return m_data->isBorderImageSliceValu e(); }
104 106 bool isCanvasValue() const { return m_data->isCanvasValue(); }
105 // ~CSSValue should be public, because non-public ~CSSValue causes C2248 107 bool isCursorImageValue() const { return m_data->isCursorImageValue(); }
106 // error: 'blink::CSSValue::~CSSValue' : cannot access protected member 108 bool isCrossfadeValue() const { return m_data->isCrossfadeValue(); }
107 // declared in class 'blink::CSSValue' when compiling 109 bool isFontFeatureValue() const { return m_data->isFontFeatureValue(); }
108 // 'source\wtf\refcounted.h' by using msvc. 110 bool isFontFaceSrcValue() const { return m_data->isFontFaceSrcValue(); }
109 ~CSSValue() { } 111 bool isFunctionValue() const { return m_data->isFunctionValue(); }
110 112 bool isImageGeneratorValue() const { return m_data->isImageGeneratorValue(); }
111 protected: 113 bool isGradientValue() const { return m_data->isGradientValue(); }
112 114 bool isImageSetValue() const { return m_data->isImageSetValue(); }
113 static const size_t ClassTypeBits = 6; 115 bool isImageValue() const { return m_data->isImageValue(); }
114 enum ClassType { 116 bool isImplicitInitialValue() const { return m_data->isImplicitInitialValue( ); };
115 PrimitiveClass, 117 bool isInheritedValue() const { return m_data->isInheritedValue(); };
116 118 bool isInitialValue() const { return m_data->isInitialValue(); };
117 // Image classes. 119 bool isUnsetValue() const { return m_data->isUnsetValue(); };
118 ImageClass, 120 bool isCSSWideKeyword() const { return m_data->isCSSWideKeyword(); };
119 CursorImageClass, 121 bool isLinearGradientValue() const { return m_data->isLinearGradientValue(); };
120 122 bool isPathValue() const { return m_data->isPathValue(); };
121 // Image generator classes. 123 bool isRadialGradientValue() const { return m_data->isRadialGradientValue(); };
122 CanvasClass, 124 bool isReflectValue() const { return m_data->isReflectValue(); };
123 CrossfadeClass, 125 bool isShadowValue() const { return m_data->isShadowValue(); };
124 LinearGradientClass, 126 bool isCubicBezierTimingFunctionValue() const { return m_data->isCubicBezier TimingFunctionValue(); };
125 RadialGradientClass, 127 bool isStepsTimingFunctionValue() const { return m_data->isStepsTimingFuncti onValue(); };
126 128 bool isLineBoxContainValue() const { return m_data->isLineBoxContainValue(); };
127 // Timing function classes. 129 bool isCalcValue() const { return m_data->isCalcValue(); };
128 CubicBezierTimingFunctionClass, 130 bool isGridTemplateAreasValue() const { return m_data->isGridTemplateAreasVa lue(); };
129 StepsTimingFunctionClass, 131 bool isSVGDocumentValue() const { return m_data->isSVGDocumentValue(); };
130 132 bool isContentDistributionValue() const { return m_data->isContentDistributi onValue(); };
131 // Other class types. 133 bool isUnicodeRangeValue() const { return m_data->isUnicodeRangeValue(); };
132 BorderImageSliceClass, 134 bool isGridLineNamesValue() const { return m_data->isGridLineNamesValue(); } ;
133 FontFeatureClass, 135
134 FontFaceSrcClass, 136 DEFINE_INLINE_TRACE()
135 137 {
136 InheritedClass, 138 ASSERT(m_data);
137 InitialClass, 139 visitor->trace(m_data);
138 UnsetClass, 140 }
139 141
140 ReflectClass, 142 // Only for use by the toFooCSSValue() macros. Don't use this.
141 ShadowClass, 143 // TODO(sashab): Remove this and use value.to<Type> and value.isValid<Type>
142 UnicodeRangeClass, 144 // like WebNode.
143 LineBoxContainClass, 145 CSSValueObject* get() const
144 CalculationClass, 146 {
145 GridTemplateAreasClass, 147 return m_data.get();
146 PathClass, 148 }
147 149
148 // SVG classes. 150 private:
149 CSSSVGDocumentClass, 151 CSSValue() = delete; // compile-time guard
150 152 CSSValue(std::nullptr_t) = delete; // compile-time guard
151 CSSContentDistributionClass, 153
152 154 void ref() const
153 // List class types must appear after ValueListClass. 155 {
154 ValueListClass, 156 #if !ENABLE(OILPAN)
155 FunctionClass, 157 if (m_data)
156 ImageSetClass, 158 m_data->ref();
157 GridLineNamesClass, 159 #endif
158 // Do not append non-list class types here. 160 }
161
162 void deref() const
163 {
164 #if !ENABLE(OILPAN)
165 if (m_data)
166 m_data->deref();
167 #endif
168 }
169
170 RawPtrWillBeMember<CSSValueObject> m_data;
171 };
172
173 // A nullable container for CSSValueObject. Contents are the same as CSSValue.
174 // Behavior is similar to a CSSValue*.
175 class CORE_EXPORT NullableCSSValue {
176 ALLOW_ONLY_INLINE_ALLOCATION();
177 public:
178 // Not explicit to allow for casting.
179 NullableCSSValue()
180 : m_data(nullptr)
181 {
182 }
183
184 NullableCSSValue(const CSSValueObject* cssValueObject)
185 : m_data(const_cast<CSSValueObject*>(cssValueObject))
186 {
187 ref();
188 }
189
190 NullableCSSValue(const CSSValueObject& cssValueObject)
191 : m_data(const_cast<CSSValueObject*>(&cssValueObject))
192 {
193 ref();
194 }
195
196 // TODO(sashab): Remove these; construction should only be available with
197 // CSSValueObject& or CSSValueObject*.
198 template <class T> NullableCSSValue(PassRefPtrWillBeRawPtr<T> cssValueObject )
199 : m_data(cssValueObject.leakRef())
200 {
201 static_assert(WTF::IsSubclass<T, CSSValueObject>::value, "Parameter must be a container for CSSValueObject");
202 }
203
204 #if !ENABLE(OILPAN)
205 template <class T> NullableCSSValue(RefPtrWillBeRawPtr<T> cssValueObject)
206 : m_data(cssValueObject.release().leakRef())
207 {
208 static_assert(WTF::IsSubclass<T, CSSValueObject>::value, "Parameter must be a container for CSSValueObject");
209 }
210 #endif
211
212 NullableCSSValue(const NullableCSSValue& cssValue)
213 : m_data(cssValue.m_data)
214 {
215 ref();
216 }
217
218 NullableCSSValue(const CSSValue& cssValue)
219 : m_data(cssValue.m_data)
220 {
221 ref();
222 }
223
224 ~NullableCSSValue()
225 {
226 deref();
159 }; 227 };
160 228
161 static const size_t ValueListSeparatorBits = 2; 229 operator bool() const
162 enum ValueListSeparator { 230 {
163 SpaceSeparator, 231 return m_data;
164 CommaSeparator, 232 }
165 SlashSeparator 233
166 }; 234 NullableCSSValue& operator=(const NullableCSSValue& rhs)
167 235 {
168 ClassType classType() const { return static_cast<ClassType>(m_classType); } 236 rhs.ref();
169 237 deref();
170 explicit CSSValue(ClassType classType) 238 m_data = rhs.m_data;
171 : m_primitiveUnitType(0) 239 return *this;
172 , m_hasCachedCSSText(false) 240 }
173 , m_isQuirkValue(false) 241
174 , m_valueListSeparator(SpaceSeparator) 242 bool operator==(const NullableCSSValue& rhs)
175 , m_classType(classType) 243 {
176 { 244 return m_data ? rhs.m_data && m_data->equals(*rhs.m_data) : !bool(rhs.m_ data);
177 } 245 }
178 246
179 // NOTE: This class is non-virtual for memory and performance reasons. 247 bool operator!=(const NullableCSSValue& rhs)
180 // Don't go making it virtual again unless you know exactly what you're doin g! 248 {
249 return !(*this == rhs);
250 }
251
252 CSSValue& operator*()
253 {
254 ASSERT(m_data);
255 // reinterpret_casts used to avoid ref-churn.
256 return *reinterpret_cast<CSSValue*>(this);
257 }
258
259 const CSSValue& operator*() const
260 {
261 ASSERT(m_data);
262 return *reinterpret_cast<const CSSValue*>(this);
263 }
264
265 CSSValue* operator->()
266 {
267 ASSERT(m_data);
268 return reinterpret_cast<CSSValue*>(this);
269 }
270
271 const CSSValue* operator->() const
272 {
273 ASSERT(m_data);
274 return reinterpret_cast<const CSSValue*>(this);
275 }
276
277 void swap(NullableCSSValue& rhs)
278 {
279 std::swap(this->m_data, rhs.m_data);
280 }
281
282 DEFINE_INLINE_TRACE()
283 {
284 visitor->trace(m_data);
285 }
286
287 // Only for use by the toFooCSSValue() macros. Don't use this.
288 // TODO(sashab): Remove this and use value.to<Type> and value.isValid<Type>
289 // like WebNode.
290 CSSValueObject* get() const
291 {
292 return m_data.get();
293 }
181 294
182 private: 295 private:
183 void destroy(); 296 void ref() const
184 297 {
185 protected: 298 #if !ENABLE(OILPAN)
186 // The bits in this section are only used by specific subclasses but kept he re 299 if (m_data)
187 // to maximize struct packing. 300 m_data->ref();
188 301 #endif
189 // CSSPrimitiveValue bits: 302 }
190 unsigned m_primitiveUnitType : 7; // CSSPrimitiveValue::UnitType 303
191 mutable unsigned m_hasCachedCSSText : 1; 304 void deref() const
192 unsigned m_isQuirkValue : 1; 305 {
193 306 #if !ENABLE(OILPAN)
194 unsigned m_valueListSeparator : ValueListSeparatorBits; 307 if (m_data)
195 308 m_data->deref();
196 private: 309 #endif
197 unsigned m_classType : ClassTypeBits; // ClassType 310 }
311
312 RawPtrWillBeMember<CSSValueObject> m_data;
198 }; 313 };
199 314
200 template<typename CSSValueType, size_t inlineCapacity> 315 static_assert(sizeof(CSSValue) == sizeof(void*), "CSSValue should be pointer-siz ed");
201 inline bool compareCSSValueVector(const WillBeHeapVector<RefPtrWillBeMember<CSSV alueType>, inlineCapacity>& firstVector, const WillBeHeapVector<RefPtrWillBeMemb er<CSSValueType>, inlineCapacity>& secondVector) 316 static_assert(sizeof(NullableCSSValue) == sizeof(void*), "CSSValue should be poi nter-sized");
317 static_assert(sizeof(CSSValue) == sizeof(NullableCSSValue), "Both CSSValue conta iners must contain the same data");
318
319 template<size_t inlineCapacity>
320 inline bool compareCSSValueVector(const WillBeHeapVector<CSSValue, inlineCapacit y>& firstVector, const WillBeHeapVector<CSSValue, inlineCapacity>& secondVector)
202 { 321 {
203 size_t size = firstVector.size(); 322 size_t size = firstVector.size();
204 if (size != secondVector.size()) 323 if (size != secondVector.size())
205 return false; 324 return false;
206 325
207 for (size_t i = 0; i < size; i++) { 326 for (size_t i = 0; i < size; i++) {
208 const RefPtrWillBeMember<CSSValueType>& firstPtr = firstVector[i]; 327 const CSSValue& firstPtr = firstVector[i];
209 const RefPtrWillBeMember<CSSValueType>& secondPtr = secondVector[i]; 328 const CSSValue& secondPtr = secondVector[i];
210 if (firstPtr == secondPtr || (firstPtr && secondPtr && firstPtr->equals( *secondPtr))) 329 if (firstPtr.ptrEquals(secondPtr) || firstPtr.equals(secondPtr))
211 continue; 330 continue;
212 return false; 331 return false;
213 } 332 }
214 return true; 333 return true;
215 } 334 }
216 335
217 template<typename CSSValueType>
218 inline bool compareCSSValuePtr(const RefPtr<CSSValueType>& first, const RefPtr<C SSValueType>& second)
219 {
220 if (first == second)
221 return true;
222 if (!first || !second)
223 return false;
224 return first->equals(*second);
225 }
226
227 template<typename CSSValueType>
228 inline bool compareCSSValuePtr(const RawPtr<CSSValueType>& first, const RawPtr<C SSValueType>& second)
229 {
230 if (first == second)
231 return true;
232 if (!first || !second)
233 return false;
234 return first->equals(*second);
235 }
236
237 template<typename CSSValueType>
238 inline bool compareCSSValuePtr(const Member<CSSValueType>& first, const Member<C SSValueType>& second)
239 {
240 if (first == second)
241 return true;
242 if (!first || !second)
243 return false;
244 return first->equals(*second);
245 }
246
247 #define DEFINE_CSS_VALUE_TYPE_CASTS(thisType, predicate) \ 336 #define DEFINE_CSS_VALUE_TYPE_CASTS(thisType, predicate) \
248 DEFINE_TYPE_CASTS(thisType, CSSValue, value, value->predicate, value.predica te) 337 DEFINE_TYPE_CASTS(thisType, CSSValueObject, value, value->predicate, value.p redicate); \
338 inline thisType& to##thisType(const CSSValue& value) \
339 { \
340 ASSERT_WITH_SECURITY_IMPLICATION(value.predicate); \
341 return *static_cast<thisType*>(value.get()); \
342 } \
343 inline thisType* to##thisType(const NullableCSSValue& value) \
344 { \
345 if (!value) \
346 return nullptr; \
347 ASSERT_WITH_SECURITY_IMPLICATION(value->predicate); \
348 return static_cast<thisType*>(value.get()); \
349 }
249 350
250 } // namespace blink 351 } // namespace blink
251 352
353 WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::CSSValue);
354 WTF_ALLOW_CLEAR_UNUSED_SLOTS_WITH_MEM_FUNCTIONS(blink::NullableCSSValue);
355
252 #endif // CSSValue_h 356 #endif // CSSValue_h
OLDNEW
« no previous file with comments | « Source/core/css/CSSUnsetValue.h ('k') | Source/core/css/CSSValue.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698