Index: Source/core/css/CSSValue.h |
diff --git a/Source/core/css/CSSValue.h b/Source/core/css/CSSValue.h |
index 7bec2acc42b668100407563f551f0c63e2ee7c00..0fdf32cfc4fe0b9451f60f06e25c857853b7572b 100644 |
--- a/Source/core/css/CSSValue.h |
+++ b/Source/core/css/CSSValue.h |
@@ -31,6 +31,23 @@ |
namespace blink { |
+class CSSValue; |
+ |
+struct CSSTaggedPtrValue { |
+ // Variables for accessing parts of the tagged pointer. |
+ // 32 bits = <value 25 bits><type 6 bits><tag 1 bit> |
+ // 64 bits = <value 57 bits><type 6 bits><tag 1 bit> |
+ unsigned flag : 1; |
+ unsigned type : 6; |
+#if CPU(32BIT) |
+ unsigned long long value : 25; |
+#elif CPU(64BIT) |
+ unsigned long long value : 57; |
+#endif |
+}; |
+ |
+// In some cases, CSSValue is a tagged pointer. If isTaggedPtr() returns true, |
+// |this| is an invalid pointer and member variables should not be accessed. |
class CORE_EXPORT CSSValue : public RefCountedWillBeGarbageCollectedFinalized<CSSValue> { |
public: |
#if ENABLE(OILPAN) |
@@ -47,52 +64,58 @@ public: |
return Heap::allocateOnHeapIndex(state, size, isEager ? ThreadState::EagerSweepHeapIndex : ThreadState::CSSValueHeapIndex, GCInfoTrait<CSSValue>::index()); |
} |
#else |
+ void ref() |
+ { |
+ if (!isTaggedPtr()) |
+ RefCountedBase::ref(); |
+ } |
+ |
// Override RefCounted's deref() to ensure operator delete is called on |
// the appropriate subclass type. |
void deref() |
{ |
- if (derefBase()) |
+ if (!isTaggedPtr() && derefBase()) |
destroy(); |
} |
#endif // !ENABLE(OILPAN) |
String cssText() const; |
- bool isPrimitiveValue() const { return m_classType == PrimitiveClass; } |
- bool isValueList() const { return m_classType >= ValueListClass; } |
- |
- bool isBaseValueList() const { return m_classType == ValueListClass; } |
- |
- bool isBorderImageSliceValue() const { return m_classType == BorderImageSliceClass; } |
- bool isCanvasValue() const { return m_classType == CanvasClass; } |
- bool isCursorImageValue() const { return m_classType == CursorImageClass; } |
- bool isCrossfadeValue() const { return m_classType == CrossfadeClass; } |
- bool isFontFeatureValue() const { return m_classType == FontFeatureClass; } |
- bool isFontFaceSrcValue() const { return m_classType == FontFaceSrcClass; } |
- bool isFunctionValue() const { return m_classType == FunctionClass; } |
- bool isImageGeneratorValue() const { return m_classType >= CanvasClass && m_classType <= RadialGradientClass; } |
- bool isGradientValue() const { return m_classType >= LinearGradientClass && m_classType <= RadialGradientClass; } |
- bool isImageSetValue() const { return m_classType == ImageSetClass; } |
- bool isImageValue() const { return m_classType == ImageClass; } |
+ bool isPrimitiveValue() const { return isTaggedPtr() || m_classType == PrimitiveClass; } |
+ bool isValueList() const { return !isTaggedPtr() && m_classType >= ValueListClass; } |
+ |
+ bool isBaseValueList() const { return !isTaggedPtr() && m_classType == ValueListClass; } |
+ |
+ bool isBorderImageSliceValue() const { return !isTaggedPtr() && m_classType == BorderImageSliceClass; } |
+ bool isCanvasValue() const { return !isTaggedPtr() && m_classType == CanvasClass; } |
+ bool isCursorImageValue() const { return !isTaggedPtr() && m_classType == CursorImageClass; } |
+ bool isCrossfadeValue() const { return !isTaggedPtr() && m_classType == CrossfadeClass; } |
+ bool isFontFeatureValue() const { return !isTaggedPtr() && m_classType == FontFeatureClass; } |
+ bool isFontFaceSrcValue() const { return !isTaggedPtr() && m_classType == FontFaceSrcClass; } |
+ bool isFunctionValue() const { return !isTaggedPtr() && m_classType == FunctionClass; } |
+ bool isImageGeneratorValue() const { return !isTaggedPtr() && m_classType >= CanvasClass && m_classType <= RadialGradientClass; } |
+ bool isGradientValue() const { return !isTaggedPtr() && m_classType >= LinearGradientClass && m_classType <= RadialGradientClass; } |
+ bool isImageSetValue() const { return !isTaggedPtr() && m_classType == ImageSetClass; } |
+ bool isImageValue() const { return !isTaggedPtr() && m_classType == ImageClass; } |
bool isImplicitInitialValue() const; |
- bool isInheritedValue() const { return m_classType == InheritedClass; } |
- bool isInitialValue() const { return m_classType == InitialClass; } |
- bool isUnsetValue() const { return m_classType == UnsetClass; } |
- bool isCSSWideKeyword() const { return m_classType >= InheritedClass && m_classType <= UnsetClass; } |
- bool isLinearGradientValue() const { return m_classType == LinearGradientClass; } |
- bool isPathValue() const { return m_classType == PathClass; } |
- bool isRadialGradientValue() const { return m_classType == RadialGradientClass; } |
- bool isReflectValue() const { return m_classType == ReflectClass; } |
- bool isShadowValue() const { return m_classType == ShadowClass; } |
- bool isCubicBezierTimingFunctionValue() const { return m_classType == CubicBezierTimingFunctionClass; } |
- bool isStepsTimingFunctionValue() const { return m_classType == StepsTimingFunctionClass; } |
- bool isLineBoxContainValue() const { return m_classType == LineBoxContainClass; } |
- bool isCalcValue() const {return m_classType == CalculationClass; } |
- bool isGridTemplateAreasValue() const { return m_classType == GridTemplateAreasClass; } |
- bool isSVGDocumentValue() const { return m_classType == CSSSVGDocumentClass; } |
- bool isContentDistributionValue() const { return m_classType == CSSContentDistributionClass; } |
- bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; } |
- bool isGridLineNamesValue() const { return m_classType == GridLineNamesClass; } |
+ bool isInheritedValue() const { return !isTaggedPtr() && m_classType == InheritedClass; } |
+ bool isInitialValue() const { return !isTaggedPtr() && m_classType == InitialClass; } |
+ bool isUnsetValue() const { return !isTaggedPtr() && m_classType == UnsetClass; } |
+ bool isCSSWideKeyword() const { return !isTaggedPtr() && m_classType >= InheritedClass && m_classType <= UnsetClass; } |
+ bool isLinearGradientValue() const { return !isTaggedPtr() && m_classType == LinearGradientClass; } |
+ bool isPathValue() const { return !isTaggedPtr() && m_classType == PathClass; } |
+ bool isRadialGradientValue() const { return !isTaggedPtr() && m_classType == RadialGradientClass; } |
+ bool isReflectValue() const { return !isTaggedPtr() && m_classType == ReflectClass; } |
+ bool isShadowValue() const { return !isTaggedPtr() && m_classType == ShadowClass; } |
+ bool isCubicBezierTimingFunctionValue() const { return !isTaggedPtr() && m_classType == CubicBezierTimingFunctionClass; } |
+ bool isStepsTimingFunctionValue() const { return !isTaggedPtr() && m_classType == StepsTimingFunctionClass; } |
+ bool isLineBoxContainValue() const { return !isTaggedPtr() && m_classType == LineBoxContainClass; } |
+ bool isCalcValue() const {return !isTaggedPtr() && m_classType == CalculationClass; } |
+ bool isGridTemplateAreasValue() const { return !isTaggedPtr() && m_classType == GridTemplateAreasClass; } |
+ bool isSVGDocumentValue() const { return !isTaggedPtr() && m_classType == CSSSVGDocumentClass; } |
+ bool isContentDistributionValue() const { return !isTaggedPtr() && m_classType == CSSContentDistributionClass; } |
+ bool isUnicodeRangeValue() const { return !isTaggedPtr() && m_classType == UnicodeRangeClass; } |
+ bool isGridLineNamesValue() const { return !isTaggedPtr() && m_classType == GridLineNamesClass; } |
bool hasFailedOrCanceledSubresources() const; |
@@ -174,6 +197,7 @@ protected: |
, m_valueListSeparator(SpaceSeparator) |
, m_classType(classType) |
{ |
+ ASSERT(!isTaggedPtr()); |
} |
// NOTE: This class is non-virtual for memory and performance reasons. |
@@ -195,6 +219,11 @@ protected: |
private: |
unsigned m_classType : ClassTypeBits; // ClassType |
+ |
+ inline bool isTaggedPtr() const |
+ { |
+ return reinterpret_cast<uintptr_t>(this) & 1; |
+ } |
}; |
template<typename CSSValueType, size_t inlineCapacity> |
@@ -249,4 +278,19 @@ inline bool compareCSSValuePtr(const Member<CSSValueType>& first, const Member<C |
} // namespace blink |
+namespace WTF { |
+ |
+#if !ENABLE(OILPAN) |
+// Must be defined *after* CSSValue to compile with the correct adopted() method. |
+template<> inline PassRefPtr<blink::CSSValue> adoptRef(blink::CSSValue* p) |
+{ |
+ // Immediates (non-pointers) end in a 1. |
+ if (!(reinterpret_cast<uintptr_t>(p) & 1)) |
+ WTF::adopted(p); |
+ return PassRefPtr<blink::CSSValue>(p, PassRefPtr<blink::CSSValue>::AdoptRef); |
+} |
+#endif |
+ |
+} // namespace WTF |
+ |
#endif // CSSValue_h |