Index: Source/core/css/CSSValue.cpp |
diff --git a/Source/core/css/CSSValue.cpp b/Source/core/css/CSSValue.cpp |
index a18425ece021ee015879c473b291f80669d1ef4f..1ab5e400fd4dc4cf0488638c432382308f29f425 100644 |
--- a/Source/core/css/CSSValue.cpp |
+++ b/Source/core/css/CSSValue.cpp |
@@ -30,6 +30,7 @@ |
#include "core/css/CSSBorderImageSliceValue.h" |
#include "core/css/CSSCanvasValue.h" |
#include "core/css/CSSContentDistributionValue.h" |
+#include "core/css/CSSCounterValue.h" |
#include "core/css/CSSCrossfadeValue.h" |
#include "core/css/CSSCursorImageValue.h" |
#include "core/css/CSSFontFaceSrcValue.h" |
@@ -61,6 +62,13 @@ struct SameSizeAsCSSValue : public RefCountedWillBeGarbageCollectedFinalized<Sam |
static_assert(sizeof(CSSValue) <= sizeof(SameSizeAsCSSValue), "CSSValue should stay small"); |
+typedef HashMap<const CSSValue*, String> CSSTextCache; |
+static CSSTextCache& cssTextCache() |
+{ |
+ AtomicallyInitializedStaticReference(ThreadSpecific<CSSTextCache>, cache, new ThreadSpecific<CSSTextCache>()); |
+ return *cache; |
+} |
+ |
bool CSSValue::isImplicitInitialValue() const |
{ |
return m_classType == InitialClass && toCSSInitialValue(this)->isImplicit(); |
@@ -96,6 +104,8 @@ bool CSSValue::equals(const CSSValue& other) const |
return compareCSSValues<CSSBorderImageSliceValue>(*this, other); |
case CanvasClass: |
return compareCSSValues<CSSCanvasValue>(*this, other); |
+ case CounterClass: |
+ return compareCSSValues<CSSCounterValue>(*this, other); |
case CursorImageClass: |
return compareCSSValues<CSSCursorImageValue>(*this, other); |
case FontFaceSrcClass: |
@@ -156,68 +166,112 @@ bool CSSValue::equals(const CSSValue& other) const |
String CSSValue::cssText() const |
{ |
+ if (m_hasCachedCSSText) { |
+ ASSERT(cssTextCache().contains(this)); |
+ return cssTextCache().get(this); |
+ } |
+ |
+ String text; |
Timothy Loh
2015/08/21 07:33:12
String CSSValue::uncachedCSSText() const { .. }?
sashab
2015/08/24 01:36:11
Should I do this in CSSPrimitiveValue? Not sure ho
|
switch (classType()) { |
case BorderImageSliceClass: |
- return toCSSBorderImageSliceValue(this)->customCSSText(); |
+ text = toCSSBorderImageSliceValue(this)->customCSSText(); |
+ break; |
case CanvasClass: |
- return toCSSCanvasValue(this)->customCSSText(); |
+ text = toCSSCanvasValue(this)->customCSSText(); |
+ break; |
+ case CounterClass: |
+ text = toCSSCounterValue(this)->customCSSText(); |
+ break; |
case CursorImageClass: |
- return toCSSCursorImageValue(this)->customCSSText(); |
+ text = toCSSCursorImageValue(this)->customCSSText(); |
+ break; |
case FontFaceSrcClass: |
- return toCSSFontFaceSrcValue(this)->customCSSText(); |
+ text = toCSSFontFaceSrcValue(this)->customCSSText(); |
+ break; |
case FontFeatureClass: |
- return toCSSFontFeatureValue(this)->customCSSText(); |
+ text = toCSSFontFeatureValue(this)->customCSSText(); |
+ break; |
case FunctionClass: |
- return toCSSFunctionValue(this)->customCSSText(); |
+ text = toCSSFunctionValue(this)->customCSSText(); |
+ break; |
case LinearGradientClass: |
- return toCSSLinearGradientValue(this)->customCSSText(); |
+ text = toCSSLinearGradientValue(this)->customCSSText(); |
+ break; |
case RadialGradientClass: |
- return toCSSRadialGradientValue(this)->customCSSText(); |
+ text = toCSSRadialGradientValue(this)->customCSSText(); |
+ break; |
case CrossfadeClass: |
- return toCSSCrossfadeValue(this)->customCSSText(); |
+ text = toCSSCrossfadeValue(this)->customCSSText(); |
+ break; |
case ImageClass: |
- return toCSSImageValue(this)->customCSSText(); |
+ text = toCSSImageValue(this)->customCSSText(); |
+ break; |
case InheritedClass: |
- return toCSSInheritedValue(this)->customCSSText(); |
+ text = toCSSInheritedValue(this)->customCSSText(); |
+ break; |
case UnsetClass: |
- return toCSSUnsetValue(this)->customCSSText(); |
+ text = toCSSUnsetValue(this)->customCSSText(); |
+ break; |
case InitialClass: |
- return toCSSInitialValue(this)->customCSSText(); |
+ text = toCSSInitialValue(this)->customCSSText(); |
+ break; |
case GridLineNamesClass: |
- return toCSSGridLineNamesValue(this)->customCSSText(); |
+ text = toCSSGridLineNamesValue(this)->customCSSText(); |
+ break; |
case GridTemplateAreasClass: |
- return toCSSGridTemplateAreasValue(this)->customCSSText(); |
+ text = toCSSGridTemplateAreasValue(this)->customCSSText(); |
+ break; |
case PathClass: |
- return toCSSPathValue(this)->customCSSText(); |
+ text = toCSSPathValue(this)->customCSSText(); |
+ break; |
case PrimitiveClass: |
- return toCSSPrimitiveValue(this)->customCSSText(); |
+ text = toCSSPrimitiveValue(this)->customCSSText(); |
+ break; |
case ReflectClass: |
- return toCSSReflectValue(this)->customCSSText(); |
+ text = toCSSReflectValue(this)->customCSSText(); |
+ break; |
case ShadowClass: |
- return toCSSShadowValue(this)->customCSSText(); |
+ text = toCSSShadowValue(this)->customCSSText(); |
+ break; |
case CubicBezierTimingFunctionClass: |
- return toCSSCubicBezierTimingFunctionValue(this)->customCSSText(); |
+ text = toCSSCubicBezierTimingFunctionValue(this)->customCSSText(); |
+ break; |
case StepsTimingFunctionClass: |
- return toCSSStepsTimingFunctionValue(this)->customCSSText(); |
+ text = toCSSStepsTimingFunctionValue(this)->customCSSText(); |
+ break; |
case UnicodeRangeClass: |
- return toCSSUnicodeRangeValue(this)->customCSSText(); |
+ text = toCSSUnicodeRangeValue(this)->customCSSText(); |
+ break; |
case ValueListClass: |
- return toCSSValueList(this)->customCSSText(); |
+ text = toCSSValueList(this)->customCSSText(); |
+ break; |
case LineBoxContainClass: |
- return toCSSLineBoxContainValue(this)->customCSSText(); |
+ text = toCSSLineBoxContainValue(this)->customCSSText(); |
+ break; |
case ImageSetClass: |
- return toCSSImageSetValue(this)->customCSSText(); |
+ text = toCSSImageSetValue(this)->customCSSText(); |
+ break; |
case CSSSVGDocumentClass: |
- return toCSSSVGDocumentValue(this)->customCSSText(); |
+ text = toCSSSVGDocumentValue(this)->customCSSText(); |
+ break; |
case CSSContentDistributionClass: |
- return toCSSContentDistributionValue(this)->customCSSText(); |
+ text = toCSSContentDistributionValue(this)->customCSSText(); |
+ break; |
} |
- ASSERT_NOT_REACHED(); |
- return String(); |
+ |
+ ASSERT(!cssTextCache().contains(this)); |
+ cssTextCache().set(this, text); |
+ m_hasCachedCSSText = true; |
+ return text; |
} |
void CSSValue::destroy() |
{ |
+ if (m_hasCachedCSSText) { |
+ cssTextCache().remove(this); |
+ m_hasCachedCSSText = false; |
+ } |
+ |
switch (classType()) { |
case BorderImageSliceClass: |
delete toCSSBorderImageSliceValue(this); |
@@ -225,6 +279,9 @@ void CSSValue::destroy() |
case CanvasClass: |
delete toCSSCanvasValue(this); |
return; |
+ case CounterClass: |
+ delete toCSSCounterValue(this); |
+ return; |
case CursorImageClass: |
delete toCSSCursorImageValue(this); |
return; |
@@ -313,6 +370,9 @@ void CSSValue::finalizeGarbageCollectedObject() |
case CanvasClass: |
toCSSCanvasValue(this)->~CSSCanvasValue(); |
return; |
+ case CounterClass: |
+ toCSSCounterValue(this)->~CSSCounterValue(); |
+ return; |
case CursorImageClass: |
toCSSCursorImageValue(this)->~CSSCursorImageValue(); |
return; |
@@ -401,6 +461,9 @@ DEFINE_TRACE(CSSValue) |
case CanvasClass: |
toCSSCanvasValue(this)->traceAfterDispatch(visitor); |
return; |
+ case CounterClass: |
+ toCSSCounterValue(this)->traceAfterDispatch(visitor); |
+ return; |
case CursorImageClass: |
toCSSCursorImageValue(this)->traceAfterDispatch(visitor); |
return; |