| 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
|
|
|