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

Unified 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: Some small fixes to (hopefully) fix some broken tests Created 5 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: Source/core/css/CSSValue.h
diff --git a/Source/core/css/CSSValue.h b/Source/core/css/CSSValue.h
index 1c0f64f7244171c87332c0632fc4e4e7b64a6aee..6749dd6bc73a7fbba84810f9595e31853d68a70d 100644
--- a/Source/core/css/CSSValue.h
+++ b/Source/core/css/CSSValue.h
@@ -31,10 +31,10 @@
namespace blink {
Timothy Loh 2015/06/02 04:54:03 This stuff should be moved to CSSValueObject.{h,cp
sashab 2015/06/05 06:16:29 Done.
-class CORE_EXPORT CSSValue : public RefCountedWillBeGarbageCollectedFinalized<CSSValue> {
+class CORE_EXPORT CSSValueObject : public RefCountedWillBeGarbageCollectedFinalized<CSSValueObject> {
public:
#if ENABLE(OILPAN)
- // Override operator new to allocate CSSValue subtype objects onto
+ // Override operator new to allocate CSSValueObject subtype objects onto
// a dedicated heap.
GC_PLUGIN_IGNORE("crbug.com/443854")
void* operator new(size_t size)
@@ -43,8 +43,8 @@ public:
}
static void* allocateObject(size_t size)
{
- ThreadState* state = ThreadStateFor<ThreadingTrait<CSSValue>::Affinity>::state();
- return Heap::allocateOnHeapIndex(state, size, CSSValueHeapIndex, GCInfoTrait<CSSValue>::index());
+ ThreadState* state = ThreadStateFor<ThreadingTrait<CSSValueObject>::Affinity>::state();
+ return Heap::allocateOnHeapIndex(state, size, CSSValueHeapIndex, GCInfoTrait<CSSValueObject>::index());
}
#else
// Override RefCounted's deref() to ensure operator delete is called on
@@ -96,17 +96,17 @@ public:
bool hasFailedOrCanceledSubresources() const;
- bool equals(const CSSValue&) const;
+ bool equals(const CSSValueObject&) const;
void finalizeGarbageCollectedObject();
DEFINE_INLINE_TRACE_AFTER_DISPATCH() { }
DECLARE_TRACE();
- // ~CSSValue should be public, because non-public ~CSSValue causes C2248
- // error: 'blink::CSSValue::~CSSValue' : cannot access protected member
- // declared in class 'blink::CSSValue' when compiling
+ // ~CSSValueObject should be public, because non-public ~CSSValueObject causes C2248
+ // error: 'blink::CSSValueObject::~CSSValueObject' : cannot access protected member
+ // declared in class 'blink::CSSValueObject' when compiling
// 'source\wtf\refcounted.h' by using msvc.
- ~CSSValue() { }
+ ~CSSValueObject() { }
protected:
@@ -167,7 +167,7 @@ protected:
ClassType classType() const { return static_cast<ClassType>(m_classType); }
- explicit CSSValue(ClassType classType)
+ explicit CSSValueObject(ClassType classType)
: m_primitiveUnitType(0)
, m_hasCachedCSSText(false)
, m_isQuirkValue(false)
@@ -197,16 +197,269 @@ private:
unsigned m_classType : ClassTypeBits; // ClassType
};
-template<typename CSSValueType, size_t inlineCapacity>
-inline bool compareCSSValueVector(const WillBeHeapVector<RefPtrWillBeMember<CSSValueType>, inlineCapacity>& firstVector, const WillBeHeapVector<RefPtrWillBeMember<CSSValueType>, inlineCapacity>& secondVector)
+// A non-nullable container for CSSValueObject. Takes ownership of the passed
+// CSSValueObject.
+class CORE_EXPORT CSSValue : public NoBaseWillBeGarbageCollectedFinalized<CSSValue> {
+ friend class NullableCSSValue;
+public:
+ // Not explicit to allow for casting.
+ CSSValue(const CSSValueObject* cssValueObject)
Timothy Loh 2015/06/02 04:54:03 This ctor seems wrong, I think we should be creati
sashab 2015/06/05 06:16:30 Done.
+ : m_data(const_cast<CSSValueObject*>(cssValueObject))
+ {
+ ASSERT(m_data);
+ m_data->ref();
+ }
+
+ template<class T> CSSValue(PassRefPtrWillBeRawPtr<T> cssValueObject)
+ : m_data(cssValueObject.leakRef())
+ {
+ ASSERT(m_data);
+ m_data->ref();
+ }
+
+ template <class T> CSSValue(RefPtrWillBeRawPtr<T> cssValueObject)
Timothy Loh 2015/06/02 04:54:03 extra space after template :|
sashab 2015/06/05 06:16:29 Ty! Didn't notice
+ : m_data(cssValueObject.release().leakRef())
+ {
+ ASSERT(m_data);
+ m_data->ref();
+ }
+
+ CSSValue(const CSSValue& cssValue)
+ : m_data(cssValue.m_data)
+ {
+ m_data->ref();
+ }
+
+ ~CSSValue()
+ {
+ m_data->deref();
+ }
+
+ CSSValue& operator=(const CSSValue& rhs)
+ {
+ m_data->deref();
Timothy Loh 2015/06/02 04:54:03 Should switch order of ref and deref so that assig
sashab 2015/06/05 06:16:30 Ah, good one!
+ rhs.m_data->ref();
+ m_data = rhs.m_data;
+ return *this;
+ }
+
+ bool operator==(const CSSValue& other) const
+ {
+ return m_data->equals(*other.m_data);
+ }
+
+ // TODO: Remove this and update callsites to use operator== instead.
+ bool equals(const CSSValue& other) const
+ {
+ return m_data->equals(*other.m_data);
+ }
+
+ bool ptrEquals(const CSSValue& other) const
+ {
+ return m_data == other.m_data;
+ }
+
+ // Methods that proxy to CSSValueObject.
+ String cssText() const { return m_data->cssText(); }
+ bool hasFailedOrCanceledSubresources() const { return m_data->hasFailedOrCanceledSubresources(); };
+ bool isPrimitiveValue() const { return m_data->isPrimitiveValue(); }
+ bool isValueList() const { return m_data->isValueList(); }
+ bool isBaseValueList() const { return m_data->isBaseValueList(); }
+ bool isBorderImageSliceValue() const { return m_data->isBorderImageSliceValue(); }
+ bool isCanvasValue() const { return m_data->isCanvasValue(); }
+ bool isCursorImageValue() const { return m_data->isCursorImageValue(); }
+ bool isCrossfadeValue() const { return m_data->isCrossfadeValue(); }
+ bool isFontFeatureValue() const { return m_data->isFontFeatureValue(); }
+ bool isFontFaceSrcValue() const { return m_data->isFontFaceSrcValue(); }
+ bool isFunctionValue() const { return m_data->isFunctionValue(); }
+ bool isImageGeneratorValue() const { return m_data->isImageGeneratorValue(); }
+ bool isGradientValue() const { return m_data->isGradientValue(); }
+ bool isImageSetValue() const { return m_data->isImageSetValue(); }
+ bool isImageValue() const { return m_data->isImageValue(); }
+ bool isImplicitInitialValue() const { return m_data->isImplicitInitialValue(); };
+ bool isInheritedValue() const { return m_data->isInheritedValue(); };
+ bool isInitialValue() const { return m_data->isInitialValue(); };
+ bool isUnsetValue() const { return m_data->isUnsetValue(); };
+ bool isCSSWideKeyword() const { return m_data->isCSSWideKeyword(); };
+ bool isLinearGradientValue() const { return m_data->isLinearGradientValue(); };
+ bool isPathValue() const { return m_data->isPathValue(); };
+ bool isRadialGradientValue() const { return m_data->isRadialGradientValue(); };
+ bool isReflectValue() const { return m_data->isReflectValue(); };
+ bool isShadowValue() const { return m_data->isShadowValue(); };
+ bool isCubicBezierTimingFunctionValue() const { return m_data->isCubicBezierTimingFunctionValue(); };
+ bool isStepsTimingFunctionValue() const { return m_data->isStepsTimingFunctionValue(); };
+ bool isLineBoxContainValue() const { return m_data->isLineBoxContainValue(); };
+ bool isCalcValue() const { return m_data->isCalcValue(); };
+ bool isGridTemplateAreasValue() const { return m_data->isGridTemplateAreasValue(); };
+ bool isSVGDocumentValue() const { return m_data->isSVGDocumentValue(); };
+ bool isContentDistributionValue() const { return m_data->isContentDistributionValue(); };
+ bool isUnicodeRangeValue() const { return m_data->isUnicodeRangeValue(); };
+ bool isGridLineNamesValue() const { return m_data->isGridLineNamesValue(); };
+
Timothy Loh 2015/06/02 04:54:04 Unused? Should call these in the above functions i
sashab 2015/06/05 06:16:30 ref() is used in: ImmutableStylePropertySet::Immut
+#if !ENABLE(OILPAN)
+ void ref()
+ {
+ m_data->ref();
+ }
+ void deref()
+ {
+ m_data->deref();
+ }
+#endif
+
+ DECLARE_TRACE();
+
+private:
+ // To ensure these are never called. Without this, the compiler may accidentally call
+ // CSSValue(nullptr) with the CSSValueObject* constructor to store an intermediate value.
+ // e.g. NullableCSSValue n = x ? CSSValue(foo) : nullptr;
+ CSSValue() { ASSERT_NOT_REACHED(); }
+ CSSValue(std::nullptr_t null) { ASSERT_NOT_REACHED(); }
Timothy Loh 2015/06/02 04:54:03 drop null argument name
sashab 2015/06/05 06:16:28 Didn't know you could do that. Done.
+
+ CSSValueObject* m_data;
+};
+
+// A nullable container for CSSValueObject. Contents are the same as CSSValue.
+// Behavior is similar to a CSSValue*.
+class CORE_EXPORT NullableCSSValue : public NoBaseWillBeGarbageCollectedFinalized<NullableCSSValue> {
+public:
+ // Not explicit to allow for casting.
+ NullableCSSValue()
+ : m_data(nullptr)
+ {
+ };
Timothy Loh 2015/06/02 04:54:04 drop semicolon
sashab 2015/06/05 06:16:30 Done.
+
+ NullableCSSValue(std::nullptr_t null)
Timothy Loh 2015/06/02 04:54:03 Is this ctor needed?
sashab 2015/06/05 06:16:30 Not anymore. Removed.
+ : m_data(nullptr)
+ {
+ };
+
+ NullableCSSValue(const CSSValueObject* cssValueObject)
+ : m_data(const_cast<CSSValueObject*>(cssValueObject))
+ {
+ if (m_data)
Timothy Loh 2015/06/02 04:54:03 should have (inline) ref/deref functions which do
sashab 2015/06/05 06:16:29 Done.
+ m_data->ref();
+ }
+
+ template <class T>
+ NullableCSSValue(PassRefPtrWillBeRawPtr<T> cssValueObject)
+ : m_data(cssValueObject.leakRef())
+ {
+ if (m_data)
+ m_data->ref();
+ }
+
+ template <class T>
+ NullableCSSValue(RefPtrWillBeRawPtr<T> cssValueObject)
+ : m_data(cssValueObject.release().leakRef())
+ {
+ if (m_data)
+ m_data->ref();
+ }
+
+ NullableCSSValue(const NullableCSSValue& cssValue)
+ : m_data(cssValue.m_data)
+ {
+ if (m_data)
+ m_data->ref();
+ }
+
+ // CSSValues can be 'auto-cast' to NullableCSSValues, but not the other way around.
Timothy Loh 2015/06/02 04:54:04 don't think this comment helps (it should be obvio
sashab 2015/06/05 06:16:29 Removed.
+ NullableCSSValue(const CSSValue& cssValue)
+ : m_data(cssValue.m_data)
+ {
+ m_data->ref();
+ }
+
+ ~NullableCSSValue()
+ {
+ if (m_data)
+ m_data->deref();
+ };
+
+ operator bool() const
+ {
+ return m_data;
+ }
+
+ NullableCSSValue& operator=(const NullableCSSValue& rhs)
+ {
+ if (m_data)
Timothy Loh 2015/06/02 04:54:04 swap order of deref/ref
sashab 2015/06/05 06:16:29 Done, as before.
+ m_data->deref();
+ if (rhs.m_data)
+ rhs.m_data->ref();
+ m_data = rhs.m_data;
+ return *this;
+ }
+
+ bool operator==(const NullableCSSValue& rhs)
+ {
+ return m_data ? rhs.m_data && m_data->equals(*rhs.m_data) : bool(rhs.m_data);
+ }
+
+ CSSValue& operator*()
+ {
+ return *reinterpret_cast<CSSValue*>(this);
Timothy Loh 2015/06/02 04:54:03 Is the reinterpret_cast to avoid ref-churn? If so,
sashab 2015/06/05 06:16:29 Done.
+ }
+
+ const CSSValue& operator*() const
+ {
+ return *reinterpret_cast<const CSSValue*>(this);
+ }
+
+ CSSValue* operator->()
+ {
+ return reinterpret_cast<CSSValue*>(this);
+ }
+
+ const CSSValue* operator->() const
+ {
+ return reinterpret_cast<const CSSValue*>(this);
+ }
+
+ void swap(NullableCSSValue& rhs)
+ {
+ std::swap(this->m_data, rhs.m_data);
+ }
+
+ DECLARE_TRACE();
+
+private:
+ CSSValueObject* m_data;
+};
+
+static_assert(sizeof(CSSValue) == sizeof(CSSValueObject*), "CSSValue must only contain a CSSValueObject*, and no vtable");
Timothy Loh 2015/06/02 04:54:03 maybe: == sizeof(void*), "CSSValue should be poin
sashab 2015/06/05 06:16:28 Done.
+static_assert(sizeof(NullableCSSValue) == sizeof(CSSValueObject*), "NullableCSSValue must only contain a CSSValueObject*, and no vtable");
+static_assert(sizeof(CSSValue) == sizeof(NullableCSSValue), "Both CSSValue containers must contain the same data members");
+
+template<size_t inlineCapacity>
+inline bool compareCSSValueVector(const WillBeHeapVector<CSSValue, inlineCapacity>& firstVector, const WillBeHeapVector<CSSValue, inlineCapacity>& secondVector)
{
size_t size = firstVector.size();
if (size != secondVector.size())
return false;
for (size_t i = 0; i < size; i++) {
- const RefPtrWillBeMember<CSSValueType>& firstPtr = firstVector[i];
- const RefPtrWillBeMember<CSSValueType>& secondPtr = secondVector[i];
+ const CSSValue& firstPtr = firstVector[i];
+ const CSSValue& secondPtr = secondVector[i];
+ if (firstPtr.ptrEquals(secondPtr) || firstPtr.equals(secondPtr))
+ continue;
+ return false;
+ }
+ return true;
+}
+
+// TODO: Rename these to CompareCSSValueObjectPtr or make them take a CSSValue
+template<typename CSSValueObjectType, size_t inlineCapacity>
+inline bool compareCSSValueObjectVector(const WillBeHeapVector<RefPtrWillBeMember<CSSValueObjectType>, inlineCapacity>& firstVector, const WillBeHeapVector<RefPtrWillBeMember<CSSValueObjectType>, inlineCapacity>& secondVector)
+{
+ size_t size = firstVector.size();
+ if (size != secondVector.size())
+ return false;
+
+ for (size_t i = 0; i < size; i++) {
+ const RefPtrWillBeMember<CSSValueObjectType>& firstPtr = firstVector[i];
+ const RefPtrWillBeMember<CSSValueObjectType>& secondPtr = secondVector[i];
if (firstPtr == secondPtr || (firstPtr && secondPtr && firstPtr->equals(*secondPtr)))
continue;
return false;
@@ -233,7 +486,19 @@ inline bool compareCSSValuePtr(const Member<CSSValueType>& first, const Member<C
}
#define DEFINE_CSS_VALUE_TYPE_CASTS(thisType, predicate) \
- DEFINE_TYPE_CASTS(thisType, CSSValue, value, value->predicate, value.predicate)
+ DEFINE_TYPE_CASTS(thisType, CSSValueObject, value, value->predicate, value.predicate); \
+ inline thisType& to##thisType(CSSValue value) \
+ { \
+ ASSERT_WITH_SECURITY_IMPLICATION(value.predicate); \
+ return **reinterpret_cast<thisType**>(&value); \
+ } \
+ inline thisType* to##thisType(NullableCSSValue value) \
+ { \
+ if (!value) \
+ return nullptr; \
+ ASSERT_WITH_SECURITY_IMPLICATION(value->predicate); \
+ return *reinterpret_cast<thisType**>(&value); \
+ }
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698