Source/WebCore: REGRESSION (r79574): fast/dom/global-constructors.html failing on...
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 7 Mar 2011 11:19:12 +0000 (11:19 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 7 Mar 2011 11:19:12 +0000 (11:19 +0000)
https://bugs.webkit.org/show_bug.cgi?id=55166
<rdar://problem/9050430>

Reviewed by Oliver Hunt.

Make CSS primitive value cache per-document.

Test: http/tests/security/cross-origin-css-primitive.html

* Android.mk:
* CMakeLists.txt:
* GNUmakefile.am:
* WebCore.gypi:
* WebCore.pro:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* css/CSSComputedStyleDeclaration.cpp:
(WebCore::valueForNinePieceImage):
(WebCore::zoomAdjustedPixelValue):
(WebCore::zoomAdjustedNumberValue):
(WebCore::zoomAdjustedPixelValueForLength):
(WebCore::valueForReflection):
(WebCore::getPositionOffsetValue):
(WebCore::CSSComputedStyleDeclaration::currentColorOrValidColor):
(WebCore::getBorderRadiusCornerValue):
(WebCore::computedTransform):
(WebCore::getDelayValue):
(WebCore::getDurationValue):
(WebCore::CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringKeyword):
(WebCore::CSSComputedStyleDeclaration::valueForShadow):
(WebCore::valueForFamily):
(WebCore::renderTextDecorationFlagsToCSSValue):
(WebCore::fillRepeatToCSSValue):
(WebCore::fillSizeToCSSValue):
(WebCore::contentToCSSValue):
(WebCore::counterToCSSValue):
(WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
* css/CSSParser.cpp:
(WebCore::CSSParser::parseSheet):
(WebCore::CSSParser::parseRule):
(WebCore::CSSParser::parseKeyframeRule):
(WebCore::CSSParser::parseValue):
(WebCore::CSSParser::parseColor):
(WebCore::CSSParser::parseSelector):
(WebCore::CSSParser::parseDeclaration):
(WebCore::CSSParser::setStyleSheet):
(WebCore::CSSParser::parseWCSSInputProperty):
(WebCore::parseBackgroundClip):
(WebCore::CSSParser::parseFillShorthand):
(WebCore::CSSParser::parsePage):
(WebCore::CSSParser::parseSizeParameter):
(WebCore::CSSParser::parseContent):
(WebCore::CSSParser::parseAttr):
(WebCore::CSSParser::parseBackgroundColor):
(WebCore::CSSParser::parseFillPositionXY):
(WebCore::CSSParser::parseFillPosition):
(WebCore::CSSParser::parseFillRepeat):
(WebCore::CSSParser::parseFillSize):
(WebCore::CSSParser::parseFillProperty):
(WebCore::CSSParser::parseAnimationDelay):
(WebCore::CSSParser::parseAnimationDirection):
(WebCore::CSSParser::parseAnimationDuration):
(WebCore::CSSParser::parseAnimationFillMode):
(WebCore::CSSParser::parseAnimationIterationCount):
(WebCore::CSSParser::parseAnimationName):
(WebCore::CSSParser::parseAnimationPlayState):
(WebCore::CSSParser::parseAnimationProperty):
(WebCore::CSSParser::parseTransformOriginShorthand):
(WebCore::CSSParser::parseAnimationTimingFunction):
(WebCore::CSSParser::parseDashboardRegions):
(WebCore::CSSParser::parseCounterContent):
(WebCore::CSSParser::parseShape):
(WebCore::CSSParser::parseFont):
(WebCore::CSSParser::parseFontFamily):
(WebCore::CSSParser::parseFontStyle):
(WebCore::CSSParser::parseFontVariant):
(WebCore::CSSParser::parseFontWeight):
(WebCore::ShadowParseContext::ShadowParseContext):
(WebCore::ShadowParseContext::commitLength):
(WebCore::ShadowParseContext::commitStyle):
(WebCore::CSSParser::parseShadow):
(WebCore::CSSParser::parseReflect):
(WebCore::BorderImageParseContext::BorderImageParseContext):
(WebCore::BorderImageParseContext::commitNumber):
(WebCore::BorderImageParseContext::commitBorderImage):
(WebCore::CSSParser::parseBorderImage):
(WebCore::CSSParser::parseBorderRadius):
(WebCore::CSSParser::parseCounter):
(WebCore::parseDeprecatedGradientPoint):
(WebCore::parseDeprecatedGradientColorStop):
(WebCore::CSSParser::parseDeprecatedGradient):
(WebCore::valueFromSideKeyword):
(WebCore::parseGradientColorOrKeyword):
(WebCore::CSSParser::parseLinearGradient):
(WebCore::CSSParser::parseRadialGradient):
(WebCore::CSSParser::parseGradientColorStops):
(WebCore::CSSParser::parseTransform):
(WebCore::CSSParser::parseTransformOrigin):
(WebCore::CSSParser::parseTextEmphasisStyle):
* css/CSSParser.h:
(WebCore::CSSParser::primitiveValueCache):
* css/CSSPrimitiveValue.cpp:
* css/CSSPrimitiveValue.h:
(WebCore::CSSPrimitiveValue::createIdentifier):
(WebCore::CSSPrimitiveValue::createColor):
(WebCore::CSSPrimitiveValue::create):
* css/CSSPrimitiveValueCache.cpp: Added.
(WebCore::CSSPrimitiveValueCache::CSSPrimitiveValueCache):
(WebCore::CSSPrimitiveValueCache::~CSSPrimitiveValueCache):
(WebCore::CSSPrimitiveValueCache::createIdentifierValue):
(WebCore::CSSPrimitiveValueCache::createColorValue):
(WebCore::CSSPrimitiveValueCache::createValue):
* css/CSSPrimitiveValueCache.h: Added.
(WebCore::CSSPrimitiveValueCache::create):
(WebCore::CSSPrimitiveValueCache::createValue):
* dom/Document.cpp:
(WebCore::Document::cssPrimitiveValueCache):
* dom/Document.h:

LayoutTests: REGRESSION (r79574): fast/dom/global-constructors.html failing on Windows 7 Release (Tests) bots
https://bugs.webkit.org/show_bug.cgi?id=55166
<rdar://problem/9050430>

Reviewed by Oliver Hunt.

* http/tests/security/cross-origin-css-primitive-expected.txt: Added.
* http/tests/security/cross-origin-css-primitive.html: Added.
* http/tests/security/resources/cross-origin-css-primitive-iframe.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@80463 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/security/cross-origin-css-primitive-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/security/cross-origin-css-primitive.html [new file with mode: 0644]
LayoutTests/http/tests/security/resources/cross-origin-css-primitive-iframe.html [new file with mode: 0644]
Source/WebCore/Android.mk
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.am
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.pro
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/css/CSSComputedStyleDeclaration.cpp
Source/WebCore/css/CSSParser.cpp
Source/WebCore/css/CSSParser.h
Source/WebCore/css/CSSPrimitiveValue.cpp
Source/WebCore/css/CSSPrimitiveValue.h
Source/WebCore/css/CSSPrimitiveValueCache.cpp [new file with mode: 0644]
Source/WebCore/css/CSSPrimitiveValueCache.h [new file with mode: 0644]
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h

index e936264..0416aa8 100644 (file)
@@ -1,3 +1,15 @@
+2011-03-07  Antti Koivisto  <antti@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        REGRESSION (r79574): fast/dom/global-constructors.html failing on Windows 7 Release (Tests) bots 
+        https://bugs.webkit.org/show_bug.cgi?id=55166
+        <rdar://problem/9050430>
+
+        * http/tests/security/cross-origin-css-primitive-expected.txt: Added.
+        * http/tests/security/cross-origin-css-primitive.html: Added.
+        * http/tests/security/resources/cross-origin-css-primitive-iframe.html: Added.
+
 2011-03-07  Alejandro G. Castro  <alex@igalia.com>
 
         Added new GTK+ test results.
diff --git a/LayoutTests/http/tests/security/cross-origin-css-primitive-expected.txt b/LayoutTests/http/tests/security/cross-origin-css-primitive-expected.txt
new file mode 100644 (file)
index 0000000..188453e
--- /dev/null
@@ -0,0 +1,16 @@
+Test that primitive value wrappers are not shared accross documents.
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+PASSED
+PASSED
+PASSED
+PASSED
+PASSED
+PASSED
+PASSED
+PASSED
+PASSED
+
diff --git a/LayoutTests/http/tests/security/cross-origin-css-primitive.html b/LayoutTests/http/tests/security/cross-origin-css-primitive.html
new file mode 100644 (file)
index 0000000..c1ffcca
--- /dev/null
@@ -0,0 +1,32 @@
+<script>
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.dumpChildFramesAsText();
+    layoutTestController.waitUntilDone();
+}
+</script>
+<style>
+.a { width: 0px; }
+.a { width: 100px; }
+.a { width: 50%; }
+.a { width: 1; }
+.a { color: red; }
+.a { color: rgb(0,0,0); }
+.a { color: rgb(255,255,255); }
+.a { color: rgba(0,0,0,255); }
+.a { color: rgba(0,0,0,0); }
+</style>
+<script>
+primitives = new Array();
+var rules = document.getElementsByTagName('style')[0].sheet.cssRules;
+for(i = 0 ; i < rules.length; ++i) {
+    var val = rules[i].style.getPropertyCSSValue('color');
+    if (!val)
+        val =  rules[i].style.getPropertyCSSValue('width');
+    primitives.push(val);
+    val.foo = 1;
+}
+</script>
+Test that primitive value wrappers are not shared accross documents.<br>
+<iframe height=300 src="http://localhost:8000/security/resources/cross-origin-css-primitive-iframe.html"></iframe>
+
diff --git a/LayoutTests/http/tests/security/resources/cross-origin-css-primitive-iframe.html b/LayoutTests/http/tests/security/resources/cross-origin-css-primitive-iframe.html
new file mode 100644 (file)
index 0000000..319bbdb
--- /dev/null
@@ -0,0 +1,25 @@
+<head>
+<style>
+.a { width: 0px; }
+.a { width: 100px; }
+.a { width: 50%; }
+.a { width: 1; }
+.a { color: red; }
+.a { color: rgb(0,0,0); }
+.a { color: rgb(255,255,255); }
+.a { color: rgba(0,0,0,255); }
+.a { color: rgba(0,0,0,0); }
+</style>
+<script>
+primitives = new Array();
+var rules = document.getElementsByTagName('style')[0].sheet.cssRules;
+for(i = 0 ; i < rules.length; ++i) {
+    var val = rules[i].style.getPropertyCSSValue('color');
+    if (!val)
+        val =  rules[i].style.getPropertyCSSValue('width');
+    primitives.push(val);
+    document.write(val.foo ? "FAILED<br>" : "PASSED<br>");
+}
+if (window.layoutTestController)
+    layoutTestController.notifyDone();
+</script>
index 6227de9..d9cd92e 100644 (file)
@@ -50,6 +50,7 @@ LOCAL_SRC_FILES := \
        css/CSSParser.cpp \
        css/CSSParserValues.cpp \
        css/CSSPrimitiveValue.cpp \
+       css/CSSPrimitiveValueCache.cpp \
        css/CSSProperty.cpp \
        css/CSSPropertyLonghand.cpp \
        css/CSSReflectValue.cpp \
index 32446a6..ed95064 100644 (file)
@@ -639,6 +639,7 @@ SET(WebCore_SOURCES
     css/CSSParser.cpp
     css/CSSParserValues.cpp
     css/CSSPrimitiveValue.cpp
+    css/CSSPrimitiveValueCache.cpp
     css/CSSProperty.cpp
     css/CSSPropertyLonghand.cpp
     css/CSSPropertySourceData.cpp
index 2f5f9e0..75bdb59 100644 (file)
@@ -1,3 +1,125 @@
+2011-03-07  Antti Koivisto  <antti@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        REGRESSION (r79574): fast/dom/global-constructors.html failing on Windows 7 Release (Tests) bots 
+        https://bugs.webkit.org/show_bug.cgi?id=55166
+        <rdar://problem/9050430>
+        
+        Make CSS primitive value cache per-document.
+        
+        Test: http/tests/security/cross-origin-css-primitive.html
+
+        * Android.mk:
+        * CMakeLists.txt:
+        * GNUmakefile.am:
+        * WebCore.gypi:
+        * WebCore.pro:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * css/CSSComputedStyleDeclaration.cpp:
+        (WebCore::valueForNinePieceImage):
+        (WebCore::zoomAdjustedPixelValue):
+        (WebCore::zoomAdjustedNumberValue):
+        (WebCore::zoomAdjustedPixelValueForLength):
+        (WebCore::valueForReflection):
+        (WebCore::getPositionOffsetValue):
+        (WebCore::CSSComputedStyleDeclaration::currentColorOrValidColor):
+        (WebCore::getBorderRadiusCornerValue):
+        (WebCore::computedTransform):
+        (WebCore::getDelayValue):
+        (WebCore::getDurationValue):
+        (WebCore::CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringKeyword):
+        (WebCore::CSSComputedStyleDeclaration::valueForShadow):
+        (WebCore::valueForFamily):
+        (WebCore::renderTextDecorationFlagsToCSSValue):
+        (WebCore::fillRepeatToCSSValue):
+        (WebCore::fillSizeToCSSValue):
+        (WebCore::contentToCSSValue):
+        (WebCore::counterToCSSValue):
+        (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::parseSheet):
+        (WebCore::CSSParser::parseRule):
+        (WebCore::CSSParser::parseKeyframeRule):
+        (WebCore::CSSParser::parseValue):
+        (WebCore::CSSParser::parseColor):
+        (WebCore::CSSParser::parseSelector):
+        (WebCore::CSSParser::parseDeclaration):
+        (WebCore::CSSParser::setStyleSheet):
+        (WebCore::CSSParser::parseWCSSInputProperty):
+        (WebCore::parseBackgroundClip):
+        (WebCore::CSSParser::parseFillShorthand):
+        (WebCore::CSSParser::parsePage):
+        (WebCore::CSSParser::parseSizeParameter):
+        (WebCore::CSSParser::parseContent):
+        (WebCore::CSSParser::parseAttr):
+        (WebCore::CSSParser::parseBackgroundColor):
+        (WebCore::CSSParser::parseFillPositionXY):
+        (WebCore::CSSParser::parseFillPosition):
+        (WebCore::CSSParser::parseFillRepeat):
+        (WebCore::CSSParser::parseFillSize):
+        (WebCore::CSSParser::parseFillProperty):
+        (WebCore::CSSParser::parseAnimationDelay):
+        (WebCore::CSSParser::parseAnimationDirection):
+        (WebCore::CSSParser::parseAnimationDuration):
+        (WebCore::CSSParser::parseAnimationFillMode):
+        (WebCore::CSSParser::parseAnimationIterationCount):
+        (WebCore::CSSParser::parseAnimationName):
+        (WebCore::CSSParser::parseAnimationPlayState):
+        (WebCore::CSSParser::parseAnimationProperty):
+        (WebCore::CSSParser::parseTransformOriginShorthand):
+        (WebCore::CSSParser::parseAnimationTimingFunction):
+        (WebCore::CSSParser::parseDashboardRegions):
+        (WebCore::CSSParser::parseCounterContent):
+        (WebCore::CSSParser::parseShape):
+        (WebCore::CSSParser::parseFont):
+        (WebCore::CSSParser::parseFontFamily):
+        (WebCore::CSSParser::parseFontStyle):
+        (WebCore::CSSParser::parseFontVariant):
+        (WebCore::CSSParser::parseFontWeight):
+        (WebCore::ShadowParseContext::ShadowParseContext):
+        (WebCore::ShadowParseContext::commitLength):
+        (WebCore::ShadowParseContext::commitStyle):
+        (WebCore::CSSParser::parseShadow):
+        (WebCore::CSSParser::parseReflect):
+        (WebCore::BorderImageParseContext::BorderImageParseContext):
+        (WebCore::BorderImageParseContext::commitNumber):
+        (WebCore::BorderImageParseContext::commitBorderImage):
+        (WebCore::CSSParser::parseBorderImage):
+        (WebCore::CSSParser::parseBorderRadius):
+        (WebCore::CSSParser::parseCounter):
+        (WebCore::parseDeprecatedGradientPoint):
+        (WebCore::parseDeprecatedGradientColorStop):
+        (WebCore::CSSParser::parseDeprecatedGradient):
+        (WebCore::valueFromSideKeyword):
+        (WebCore::parseGradientColorOrKeyword):
+        (WebCore::CSSParser::parseLinearGradient):
+        (WebCore::CSSParser::parseRadialGradient):
+        (WebCore::CSSParser::parseGradientColorStops):
+        (WebCore::CSSParser::parseTransform):
+        (WebCore::CSSParser::parseTransformOrigin):
+        (WebCore::CSSParser::parseTextEmphasisStyle):
+        * css/CSSParser.h:
+        (WebCore::CSSParser::primitiveValueCache):
+        * css/CSSPrimitiveValue.cpp:
+        * css/CSSPrimitiveValue.h:
+        (WebCore::CSSPrimitiveValue::createIdentifier):
+        (WebCore::CSSPrimitiveValue::createColor):
+        (WebCore::CSSPrimitiveValue::create):
+        * css/CSSPrimitiveValueCache.cpp: Added.
+        (WebCore::CSSPrimitiveValueCache::CSSPrimitiveValueCache):
+        (WebCore::CSSPrimitiveValueCache::~CSSPrimitiveValueCache):
+        (WebCore::CSSPrimitiveValueCache::createIdentifierValue):
+        (WebCore::CSSPrimitiveValueCache::createColorValue):
+        (WebCore::CSSPrimitiveValueCache::createValue):
+        * css/CSSPrimitiveValueCache.h: Added.
+        (WebCore::CSSPrimitiveValueCache::create):
+        (WebCore::CSSPrimitiveValueCache::createValue):
+        * dom/Document.cpp:
+        (WebCore::Document::cssPrimitiveValueCache):
+        * dom/Document.h:
+
 2011-03-06  Adam Barth  <abarth@webkit.org>
 
         Reviewed by Eric Seidel.
index a021811..a2c7d5e 100644 (file)
@@ -1015,6 +1015,8 @@ webcore_sources += \
        Source/WebCore/css/CSSParserValues.h \
        Source/WebCore/css/CSSPrimitiveValue.cpp \
        Source/WebCore/css/CSSPrimitiveValue.h \
+       Source/WebCore/css/CSSPrimitiveValueCache.cpp \
+       Source/WebCore/css/CSSPrimitiveValueCache.h \
        Source/WebCore/css/CSSPrimitiveValueMappings.h \
        Source/WebCore/css/CSSProperty.cpp \
        Source/WebCore/css/CSSProperty.h \
index 6eab6c4..9f288d3 100644 (file)
             'css/CSSParserValues.h',
             'css/CSSPrimitiveValue.cpp',
             'css/CSSPrimitiveValue.h',
+            'css/CSSPrimitiveValueCache.cpp',
+            'css/CSSPrimitiveValueCache.h',
             'css/CSSPrimitiveValueMappings.h',
             'css/CSSProperty.cpp',
             'css/CSSProperty.h',
index f60c769..583df14 100644 (file)
@@ -396,6 +396,7 @@ SOURCES += \
     css/CSSParser.cpp \
     css/CSSParserValues.cpp \
     css/CSSPrimitiveValue.cpp \
+    css/CSSPrimitiveValueCache.cpp \
     css/CSSProperty.cpp \
     css/CSSPropertyLonghand.cpp \
     css/CSSPropertySourceData.cpp \
@@ -1346,6 +1347,7 @@ HEADERS += \
     css/CSSParser.h \
     css/CSSParserValues.h \
     css/CSSPrimitiveValue.h \
+    css/CSSPrimitiveValueCache.h \
     css/CSSProperty.h \
     css/CSSPropertyLonghand.h \
     css/CSSReflectValue.h \
index f399076..847c04f 100755 (executable)
                                >
                        </File>
                        <File
+                               RelativePath="..\css\CSSPrimitiveValueCache.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\css\CSSPrimitiveValueCache.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\css\CSSProperty.cpp"
                                >
                        </File>
index 46cda2a..e1d9768 100644 (file)
                E4778B80115A581A00B5D372 /* JSCustomEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = E4778B7E115A581A00B5D372 /* JSCustomEvent.h */; };
                E47B4BE80E71241600038854 /* CachedResourceHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = E47B4BE60E71241600038854 /* CachedResourceHandle.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E47B4BE90E71241600038854 /* CachedResourceHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E47B4BE70E71241600038854 /* CachedResourceHandle.cpp */; };
+               E49BD9FA131FD2ED003C56F0 /* CSSPrimitiveValueCache.h in Headers */ = {isa = PBXBuildFile; fileRef = E49BD9F9131FD2ED003C56F0 /* CSSPrimitiveValueCache.h */; };
+               E49BDA0B131FD3E5003C56F0 /* CSSPrimitiveValueCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E49BDA0A131FD3E5003C56F0 /* CSSPrimitiveValueCache.cpp */; };
                E4AFCFA50DAF29A300F5F55C /* UnitBezier.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AFCFA40DAF29A300F5F55C /* UnitBezier.h */; };
                E4AFD00B0DAF335400F5F55C /* SMILTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4AFD0050DAF335400F5F55C /* SMILTime.cpp */; };
                E4AFD00C0DAF335400F5F55C /* SMILTime.h in Headers */ = {isa = PBXBuildFile; fileRef = E4AFD0060DAF335400F5F55C /* SMILTime.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E4778B7E115A581A00B5D372 /* JSCustomEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSCustomEvent.h; sourceTree = "<group>"; };
                E47B4BE60E71241600038854 /* CachedResourceHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedResourceHandle.h; sourceTree = "<group>"; };
                E47B4BE70E71241600038854 /* CachedResourceHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CachedResourceHandle.cpp; sourceTree = "<group>"; };
+               E49BD9F9131FD2ED003C56F0 /* CSSPrimitiveValueCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSSPrimitiveValueCache.h; sourceTree = "<group>"; };
+               E49BDA0A131FD3E5003C56F0 /* CSSPrimitiveValueCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSPrimitiveValueCache.cpp; sourceTree = "<group>"; };
                E4AFCFA40DAF29A300F5F55C /* UnitBezier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnitBezier.h; sourceTree = "<group>"; };
                E4AFD0050DAF335400F5F55C /* SMILTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SMILTime.cpp; sourceTree = "<group>"; };
                E4AFD0060DAF335400F5F55C /* SMILTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SMILTime.h; sourceTree = "<group>"; };
                                A80E6CDB0A1989CA007FB8C5 /* CSSPrimitiveValue.cpp */,
                                A80E6CBC0A1989CA007FB8C5 /* CSSPrimitiveValue.h */,
                                9307059009E0C75800B17FE4 /* CSSPrimitiveValue.idl */,
+                               E49BD9F9131FD2ED003C56F0 /* CSSPrimitiveValueCache.h */,
+                               E49BDA0A131FD3E5003C56F0 /* CSSPrimitiveValueCache.cpp */,
                                E1ED8AC20CC49BE000BFC557 /* CSSPrimitiveValueMappings.h */,
                                A80E6CCD0A1989CA007FB8C5 /* CSSProperty.cpp */,
                                A80E6CD50A1989CA007FB8C5 /* CSSProperty.h */,
                                93F199ED08245E59001E9ABC /* XSLTProcessor.h in Headers */,
                                E1BE512E0CF6C512002EA959 /* XSLTUnicodeSort.h in Headers */,
                                977E2E0F12F0FC9C00C13379 /* XSSFilter.h in Headers */,
+                               E49BD9FA131FD2ED003C56F0 /* CSSPrimitiveValueCache.h in Headers */,
                                5A574F25131DB93900471B88 /* RenderQuote.h in Headers */,
                                5A574F29131DB96D00471B88 /* QuotesData.h in Headers */,
                                339B5B63131DAA3200F48D02 /* CookiesStrategy.h in Headers */,
                                93F19B0508245E59001E9ABC /* XSLTProcessorLibxslt.cpp in Sources */,
                                E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */,
                                977E2E0E12F0FC9C00C13379 /* XSSFilter.cpp in Sources */,
+                               E49BDA0B131FD3E5003C56F0 /* CSSPrimitiveValueCache.cpp in Sources */,
                                5A574F24131DB93900471B88 /* RenderQuote.cpp in Sources */,
                                5A574F28131DB96D00471B88 /* QuotesData.cpp in Sources */,
                                59695084132105A500C3ED18 /* JobjectWrapper.cpp in Sources */,
index abe8792..82ee50d 100644 (file)
@@ -31,6 +31,7 @@
 #include "CSSBorderImageValue.h"
 #include "CSSMutableStyleDeclaration.h"
 #include "CSSPrimitiveValue.h"
+#include "CSSPrimitiveValueCache.h"
 #include "CSSPrimitiveValueMappings.h"
 #include "CSSProperty.h"
 #include "CSSPropertyNames.h"
@@ -299,10 +300,10 @@ static int valueForRepeatRule(int rule)
     }
 }
         
-static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image)
+static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image, CSSPrimitiveValueCache* primitiveValueCache)
 {
     if (!image.hasImage())
-        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
+        return primitiveValueCache->createIdentifierValue(CSSValueNone);
     
     // Image first.
     RefPtr<CSSValue> imageValue;
@@ -312,27 +313,27 @@ static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image)
     // Create the slices.
     RefPtr<CSSPrimitiveValue> top;
     if (image.slices().top().isPercent())
-        top = CSSPrimitiveValue::create(image.slices().top().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
+        top = primitiveValueCache->createValue(image.slices().top().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
     else
-        top = CSSPrimitiveValue::create(image.slices().top().value(), CSSPrimitiveValue::CSS_NUMBER);
+        top = primitiveValueCache->createValue(image.slices().top().value(), CSSPrimitiveValue::CSS_NUMBER);
         
     RefPtr<CSSPrimitiveValue> right;
     if (image.slices().right().isPercent())
-        right = CSSPrimitiveValue::create(image.slices().right().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
+        right = primitiveValueCache->createValue(image.slices().right().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
     else
-        right = CSSPrimitiveValue::create(image.slices().right().value(), CSSPrimitiveValue::CSS_NUMBER);
+        right = primitiveValueCache->createValue(image.slices().right().value(), CSSPrimitiveValue::CSS_NUMBER);
         
     RefPtr<CSSPrimitiveValue> bottom;
     if (image.slices().bottom().isPercent())
-        bottom = CSSPrimitiveValue::create(image.slices().bottom().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
+        bottom = primitiveValueCache->createValue(image.slices().bottom().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
     else
-        bottom = CSSPrimitiveValue::create(image.slices().bottom().value(), CSSPrimitiveValue::CSS_NUMBER);
+        bottom = primitiveValueCache->createValue(image.slices().bottom().value(), CSSPrimitiveValue::CSS_NUMBER);
     
     RefPtr<CSSPrimitiveValue> left;
     if (image.slices().left().isPercent())
-        left = CSSPrimitiveValue::create(image.slices().left().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
+        left = primitiveValueCache->createValue(image.slices().left().value(), CSSPrimitiveValue::CSS_PERCENTAGE);
     else
-        left = CSSPrimitiveValue::create(image.slices().left().value(), CSSPrimitiveValue::CSS_NUMBER);
+        left = primitiveValueCache->createValue(image.slices().left().value(), CSSPrimitiveValue::CSS_NUMBER);
 
     RefPtr<Rect> rect = Rect::create();
     rect->setTop(top);
@@ -343,38 +344,38 @@ static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image)
     return CSSBorderImageValue::create(imageValue, rect, valueForRepeatRule(image.horizontalRule()), valueForRepeatRule(image.verticalRule()));
 }
 
-inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValue(int value, const RenderStyle* style)
+inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedPixelValue(int value, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache)
 {
-    return CSSPrimitiveValue::create(adjustForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX);
+    return primitiveValueCache->createValue(adjustForAbsoluteZoom(value, style), CSSPrimitiveValue::CSS_PX);
 }
 
-inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle* style)
+inline static PassRefPtr<CSSPrimitiveValue> zoomAdjustedNumberValue(double value, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache)
 {
-    return CSSPrimitiveValue::create(value / style->effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER);
+    return primitiveValueCache->createValue(value / style->effectiveZoom(), CSSPrimitiveValue::CSS_NUMBER);
 }
 
-static PassRefPtr<CSSValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle* style)
+static PassRefPtr<CSSValue> zoomAdjustedPixelValueForLength(const Length& length, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache)
 {
     if (length.isFixed())
-        return zoomAdjustedPixelValue(length.value(), style);
-    return CSSPrimitiveValue::create(length);
+        return zoomAdjustedPixelValue(length.value(), style, primitiveValueCache);
+    return primitiveValueCache->createValue(length);
 }
 
-static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle* style)
+static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache)
 {
     if (!reflection)
-        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
+        return primitiveValueCache->createIdentifierValue(CSSValueNone);
 
     RefPtr<CSSPrimitiveValue> offset;
     if (reflection->offset().isPercent())
-        offset = CSSPrimitiveValue::create(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
+        offset = primitiveValueCache->createValue(reflection->offset().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
     else
-        offset = zoomAdjustedPixelValue(reflection->offset().value(), style);
+        offset = zoomAdjustedPixelValue(reflection->offset().value(), style, primitiveValueCache);
     
-    return CSSReflectValue::create(reflection->direction(), offset.release(), valueForNinePieceImage(reflection->mask()));
+    return CSSReflectValue::create(reflection->direction(), offset.release(), valueForNinePieceImage(reflection->mask(), primitiveValueCache));
 }
 
-static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, int propertyID)
+static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, int propertyID, CSSPrimitiveValueCache* primitiveValueCache)
 {
     if (!style)
         return 0;
@@ -399,43 +400,44 @@ static PassRefPtr<CSSValue> getPositionOffsetValue(RenderStyle* style, int prope
 
     if (style->position() == AbsolutePosition || style->position() == FixedPosition) {
         if (l.type() == WebCore::Fixed)
-            return zoomAdjustedPixelValue(l.value(), style);
-        return CSSPrimitiveValue::create(l);
+            return zoomAdjustedPixelValue(l.value(), style, primitiveValueCache);
+        return primitiveValueCache->createValue(l);
     }
 
     if (style->position() == RelativePosition)
         // FIXME: It's not enough to simply return "auto" values for one offset if the other side is defined.
         // In other words if left is auto and right is not auto, then left's computed value is negative right().
         // So we should get the opposite length unit and see if it is auto.
-        return CSSPrimitiveValue::create(l);
+        return primitiveValueCache->createValue(l);
 
-    return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
+    return primitiveValueCache->createIdentifierValue(CSSValueAuto);
 }
 
 PassRefPtr<CSSPrimitiveValue> CSSComputedStyleDeclaration::currentColorOrValidColor(RenderStyle* style, const Color& color) const
 {
     // This function does NOT look at visited information, so that computed style doesn't expose that.
+    CSSPrimitiveValueCache* primitiveValueCache = m_node->document()->cssPrimitiveValueCache().get();
     if (!color.isValid())
-        return CSSPrimitiveValue::createColor(style->color().rgb());
-    return CSSPrimitiveValue::createColor(color.rgb());
+        return primitiveValueCache->createColorValue(style->color().rgb());
+    return primitiveValueCache->createColorValue(color.rgb());
 }
 
-static PassRefPtr<CSSValue> getBorderRadiusCornerValue(LengthSize radius, const RenderStyle* style)
+static PassRefPtr<CSSValue> getBorderRadiusCornerValue(LengthSize radius, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache)
 {
     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
     if (radius.width() == radius.height()) {
         if (radius.width().type() == Percent)
-            return CSSPrimitiveValue::create(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
-        return zoomAdjustedPixelValue(radius.width().value(), style);
+            return primitiveValueCache->createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE);
+        return zoomAdjustedPixelValue(radius.width().value(), style, primitiveValueCache);
     }
     if (radius.width().type() == Percent)
-        list->append(CSSPrimitiveValue::create(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE));
+        list->append(primitiveValueCache->createValue(radius.width().percent(), CSSPrimitiveValue::CSS_PERCENTAGE));
     else
-        list->append(zoomAdjustedPixelValue(radius.width().value(), style));
+        list->append(zoomAdjustedPixelValue(radius.width().value(), style, primitiveValueCache));
     if (radius.height().type() == Percent)
-        list->append(CSSPrimitiveValue::create(radius.height().percent(), CSSPrimitiveValue::CSS_PERCENTAGE));
+        list->append(primitiveValueCache->createValue(radius.height().percent(), CSSPrimitiveValue::CSS_PERCENTAGE));
     else
-        list->append(zoomAdjustedPixelValue(radius.height().value(), style));
+        list->append(zoomAdjustedPixelValue(radius.height().value(), style, primitiveValueCache));
     return list.release();
 }
 
@@ -453,10 +455,10 @@ static inline bool hasCompositedLayer(RenderObject* renderer)
     return renderer && renderer->hasLayer() && toRenderBoxModelObject(renderer)->layer()->isComposited();
 }
 
-static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle* style)
+static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache)
 {
     if (!renderer || style->transform().operations().isEmpty())
-        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
+        return primitiveValueCache->createIdentifierValue(CSSValueNone);
     
     IntRect box = sizingBox(renderer);
 
@@ -470,34 +472,34 @@ static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const Rend
     if (transform.isAffine()) {
         transformVal = WebKitCSSTransformValue::create(WebKitCSSTransformValue::MatrixTransformOperation);
 
-        transformVal->append(CSSPrimitiveValue::create(transform.a(), CSSPrimitiveValue::CSS_NUMBER));
-        transformVal->append(CSSPrimitiveValue::create(transform.b(), CSSPrimitiveValue::CSS_NUMBER));
-        transformVal->append(CSSPrimitiveValue::create(transform.c(), CSSPrimitiveValue::CSS_NUMBER));
-        transformVal->append(CSSPrimitiveValue::create(transform.d(), CSSPrimitiveValue::CSS_NUMBER));
-        transformVal->append(zoomAdjustedNumberValue(transform.e(), style));
-        transformVal->append(zoomAdjustedNumberValue(transform.f(), style));
+        transformVal->append(primitiveValueCache->createValue(transform.a(), CSSPrimitiveValue::CSS_NUMBER));
+        transformVal->append(primitiveValueCache->createValue(transform.b(), CSSPrimitiveValue::CSS_NUMBER));
+        transformVal->append(primitiveValueCache->createValue(transform.c(), CSSPrimitiveValue::CSS_NUMBER));
+        transformVal->append(primitiveValueCache->createValue(transform.d(), CSSPrimitiveValue::CSS_NUMBER));
+        transformVal->append(zoomAdjustedNumberValue(transform.e(), style, primitiveValueCache));
+        transformVal->append(zoomAdjustedNumberValue(transform.f(), style, primitiveValueCache));
     } else {
         transformVal = WebKitCSSTransformValue::create(WebKitCSSTransformValue::Matrix3DTransformOperation);
 
-        transformVal->append(CSSPrimitiveValue::create(transform.m11(), CSSPrimitiveValue::CSS_NUMBER));
-        transformVal->append(CSSPrimitiveValue::create(transform.m12(), CSSPrimitiveValue::CSS_NUMBER));
-        transformVal->append(CSSPrimitiveValue::create(transform.m13(), CSSPrimitiveValue::CSS_NUMBER));
-        transformVal->append(CSSPrimitiveValue::create(transform.m14(), CSSPrimitiveValue::CSS_NUMBER));
-
-        transformVal->append(CSSPrimitiveValue::create(transform.m21(), CSSPrimitiveValue::CSS_NUMBER));
-        transformVal->append(CSSPrimitiveValue::create(transform.m22(), CSSPrimitiveValue::CSS_NUMBER));
-        transformVal->append(CSSPrimitiveValue::create(transform.m23(), CSSPrimitiveValue::CSS_NUMBER));
-        transformVal->append(CSSPrimitiveValue::create(transform.m24(), CSSPrimitiveValue::CSS_NUMBER));
-
-        transformVal->append(CSSPrimitiveValue::create(transform.m31(), CSSPrimitiveValue::CSS_NUMBER));
-        transformVal->append(CSSPrimitiveValue::create(transform.m32(), CSSPrimitiveValue::CSS_NUMBER));
-        transformVal->append(CSSPrimitiveValue::create(transform.m33(), CSSPrimitiveValue::CSS_NUMBER));
-        transformVal->append(CSSPrimitiveValue::create(transform.m34(), CSSPrimitiveValue::CSS_NUMBER));
-
-        transformVal->append(zoomAdjustedNumberValue(transform.m41(), style));
-        transformVal->append(zoomAdjustedNumberValue(transform.m42(), style));
-        transformVal->append(zoomAdjustedNumberValue(transform.m43(), style));
-        transformVal->append(CSSPrimitiveValue::create(transform.m44(), CSSPrimitiveValue::CSS_NUMBER));
+        transformVal->append(primitiveValueCache->createValue(transform.m11(), CSSPrimitiveValue::CSS_NUMBER));
+        transformVal->append(primitiveValueCache->createValue(transform.m12(), CSSPrimitiveValue::CSS_NUMBER));
+        transformVal->append(primitiveValueCache->createValue(transform.m13(), CSSPrimitiveValue::CSS_NUMBER));
+        transformVal->append(primitiveValueCache->createValue(transform.m14(), CSSPrimitiveValue::CSS_NUMBER));
+
+        transformVal->append(primitiveValueCache->createValue(transform.m21(), CSSPrimitiveValue::CSS_NUMBER));
+        transformVal->append(primitiveValueCache->createValue(transform.m22(), CSSPrimitiveValue::CSS_NUMBER));
+        transformVal->append(primitiveValueCache->createValue(transform.m23(), CSSPrimitiveValue::CSS_NUMBER));
+        transformVal->append(primitiveValueCache->createValue(transform.m24(), CSSPrimitiveValue::CSS_NUMBER));
+
+        transformVal->append(primitiveValueCache->createValue(transform.m31(), CSSPrimitiveValue::CSS_NUMBER));
+        transformVal->append(primitiveValueCache->createValue(transform.m32(), CSSPrimitiveValue::CSS_NUMBER));
+        transformVal->append(primitiveValueCache->createValue(transform.m33(), CSSPrimitiveValue::CSS_NUMBER));
+        transformVal->append(primitiveValueCache->createValue(transform.m34(), CSSPrimitiveValue::CSS_NUMBER));
+
+        transformVal->append(zoomAdjustedNumberValue(transform.m41(), style, primitiveValueCache));
+        transformVal->append(zoomAdjustedNumberValue(transform.m42(), style, primitiveValueCache));
+        transformVal->append(zoomAdjustedNumberValue(transform.m43(), style, primitiveValueCache));
+        transformVal->append(primitiveValueCache->createValue(transform.m44(), CSSPrimitiveValue::CSS_NUMBER));
     }
 
     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
@@ -506,28 +508,28 @@ static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const Rend
     return list.release();
 }
 
-static PassRefPtr<CSSValue> getDelayValue(const AnimationList* animList)
+static PassRefPtr<CSSValue> getDelayValue(const AnimationList* animList, CSSPrimitiveValueCache* primitiveValueCache)
 {
     RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
     if (animList) {
         for (size_t i = 0; i < animList->size(); ++i)
-            list->append(CSSPrimitiveValue::create(animList->animation(i)->delay(), CSSPrimitiveValue::CSS_S));
+            list->append(primitiveValueCache->createValue(animList->animation(i)->delay(), CSSPrimitiveValue::CSS_S));
     } else {
         // Note that initialAnimationDelay() is used for both transitions and animations
-        list->append(CSSPrimitiveValue::create(Animation::initialAnimationDelay(), CSSPrimitiveValue::CSS_S));
+        list->append(primitiveValueCache->createValue(Animation::initialAnimationDelay(), CSSPrimitiveValue::CSS_S));
     }
     return list.release();
 }
 
-static PassRefPtr<CSSValue> getDurationValue(const AnimationList* animList)
+static PassRefPtr<CSSValue> getDurationValue(const AnimationList* animList, CSSPrimitiveValueCache* primitiveValueCache)
 {
     RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
     if (animList) {
         for (size_t i = 0; i < animList->size(); ++i)
-            list->append(CSSPrimitiveValue::create(animList->animation(i)->duration(), CSSPrimitiveValue::CSS_S));
+            list->append(primitiveValueCache->createValue(animList->animation(i)->duration(), CSSPrimitiveValue::CSS_S));
     } else {
         // Note that initialAnimationDuration() is used for both transitions and animations
-        list->append(CSSPrimitiveValue::create(Animation::initialAnimationDuration(), CSSPrimitiveValue::CSS_S));
+        list->append(primitiveValueCache->createValue(Animation::initialAnimationDuration(), CSSPrimitiveValue::CSS_S));
     }
     return list.release();
 }
@@ -615,12 +617,14 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringK
     RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
     if (!style)
         return 0;
+    
+    CSSPrimitiveValueCache* primitiveValueCache = m_node->document()->cssPrimitiveValueCache().get();
 
     if (int keywordSize = style->fontDescription().keywordSize())
-        return CSSPrimitiveValue::createIdentifier(cssIdentifierForFontSizeKeyword(keywordSize));
+        return primitiveValueCache->createIdentifierValue(cssIdentifierForFontSizeKeyword(keywordSize));
 
 
-    return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style.get());
+    return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style.get(), primitiveValueCache);
 }
 
 bool CSSComputedStyleDeclaration::useFixedFontDefaultSize() const
@@ -637,19 +641,20 @@ bool CSSComputedStyleDeclaration::useFixedFontDefaultSize() const
 
 PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadow(const ShadowData* shadow, int id, RenderStyle* style) const
 {
+    CSSPrimitiveValueCache* primitiveValueCache = m_node->document()->cssPrimitiveValueCache().get();
     if (!shadow)
-        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
+        return primitiveValueCache->createIdentifierValue(CSSValueNone);
 
     CSSPropertyID propertyID = static_cast<CSSPropertyID>(id);
 
     RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
     for (const ShadowData* s = shadow; s; s = s->next()) {
-        RefPtr<CSSPrimitiveValue> x = zoomAdjustedPixelValue(s->x(), style);
-        RefPtr<CSSPrimitiveValue> y = zoomAdjustedPixelValue(s->y(), style);
-        RefPtr<CSSPrimitiveValue> blur = zoomAdjustedPixelValue(s->blur(), style);
-        RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? 0 : zoomAdjustedPixelValue(s->spread(), style);
-        RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || s->style() == Normal ? 0 : CSSPrimitiveValue::createIdentifier(CSSValueInset);
-        RefPtr<CSSPrimitiveValue> color = CSSPrimitiveValue::createColor(s->color().rgb());
+        RefPtr<CSSPrimitiveValue> x = zoomAdjustedPixelValue(s->x(), style, primitiveValueCache);
+        RefPtr<CSSPrimitiveValue> y = zoomAdjustedPixelValue(s->y(), style, primitiveValueCache);
+        RefPtr<CSSPrimitiveValue> blur = zoomAdjustedPixelValue(s->blur(), style, primitiveValueCache);
+        RefPtr<CSSPrimitiveValue> spread = propertyID == CSSPropertyTextShadow ? 0 : zoomAdjustedPixelValue(s->spread(), style, primitiveValueCache);
+        RefPtr<CSSPrimitiveValue> style = propertyID == CSSPropertyTextShadow || s->style() == Normal ? 0 : primitiveValueCache->createIdentifierValue(CSSValueInset);
+        RefPtr<CSSPrimitiveValue> color = primitiveValueCache->createColorValue(s->color().rgb());
         list->prepend(ShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
     }
     return list.release();
@@ -680,87 +685,87 @@ static int identifierForFamily(const AtomicString& family)
     return 0;
 }
 
-static PassRefPtr<CSSPrimitiveValue> valueForFamily(const AtomicString& family)
+static PassRefPtr<CSSPrimitiveValue> valueForFamily(const AtomicString& family, CSSPrimitiveValueCache* primitiveValueCache)
 {
     if (int familyIdentifier = identifierForFamily(family))
-        return CSSPrimitiveValue::createIdentifier(familyIdentifier);
-    return CSSPrimitiveValue::create(family.string(), CSSPrimitiveValue::CSS_STRING);
+        return primitiveValueCache->createIdentifierValue(familyIdentifier);
+    return primitiveValueCache->createValue(family.string(), CSSPrimitiveValue::CSS_STRING);
 }
 
-static PassRefPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration)
+static PassRefPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration, CSSPrimitiveValueCache* primitiveValueCache)
 {
     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
     if (textDecoration & UNDERLINE)
-        list->append(CSSPrimitiveValue::createIdentifier(CSSValueUnderline));
+        list->append(primitiveValueCache->createIdentifierValue(CSSValueUnderline));
     if (textDecoration & OVERLINE)
-        list->append(CSSPrimitiveValue::createIdentifier(CSSValueOverline));
+        list->append(primitiveValueCache->createIdentifierValue(CSSValueOverline));
     if (textDecoration & LINE_THROUGH)
-        list->append(CSSPrimitiveValue::createIdentifier(CSSValueLineThrough));
+        list->append(primitiveValueCache->createIdentifierValue(CSSValueLineThrough));
     if (textDecoration & BLINK)
-        list->append(CSSPrimitiveValue::createIdentifier(CSSValueBlink));
+        list->append(primitiveValueCache->createIdentifierValue(CSSValueBlink));
 
     if (!list->length())
-        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
+        return primitiveValueCache->createIdentifierValue(CSSValueNone);
     return list;
 }
 
-static PassRefPtr<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat)
+static PassRefPtr<CSSValue> fillRepeatToCSSValue(EFillRepeat xRepeat, EFillRepeat yRepeat, CSSPrimitiveValueCache* primitiveValueCache)
 {
     // For backwards compatibility, if both values are equal, just return one of them. And
     // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
     if (xRepeat == yRepeat)
-        return CSSPrimitiveValue::create(xRepeat);
+        return primitiveValueCache->createValue(xRepeat);
     if (xRepeat == RepeatFill && yRepeat == NoRepeatFill)
-        return CSSPrimitiveValue::createIdentifier(CSSValueRepeatX);
+        return primitiveValueCache->createIdentifierValue(CSSValueRepeatX);
     if (xRepeat == NoRepeatFill && yRepeat == RepeatFill)
-        return CSSPrimitiveValue::createIdentifier(CSSValueRepeatY);
+        return primitiveValueCache->createIdentifierValue(CSSValueRepeatY);
 
     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
-    list->append(CSSPrimitiveValue::create(xRepeat));
-    list->append(CSSPrimitiveValue::create(yRepeat));
+    list->append(primitiveValueCache->createValue(xRepeat));
+    list->append(primitiveValueCache->createValue(yRepeat));
     return list.release();
 }
 
-static PassRefPtr<CSSValue> fillSizeToCSSValue(const FillSize& fillSize)
+static PassRefPtr<CSSValue> fillSizeToCSSValue(const FillSize& fillSize, CSSPrimitiveValueCache* primitiveValueCache)
 {
     if (fillSize.type == Contain)
-        return CSSPrimitiveValue::createIdentifier(CSSValueContain);
+        return primitiveValueCache->createIdentifierValue(CSSValueContain);
 
     if (fillSize.type == Cover)
-        return CSSPrimitiveValue::createIdentifier(CSSValueCover);
+        return primitiveValueCache->createIdentifierValue(CSSValueCover);
 
     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
-    list->append(CSSPrimitiveValue::create(fillSize.size.width()));
-    list->append(CSSPrimitiveValue::create(fillSize.size.height()));
+    list->append(primitiveValueCache->createValue(fillSize.size.width()));
+    list->append(primitiveValueCache->createValue(fillSize.size.height()));
     return list.release();
 }
 
-static PassRefPtr<CSSValue> contentToCSSValue(const RenderStyle* style)
+static PassRefPtr<CSSValue> contentToCSSValue(const RenderStyle* style, CSSPrimitiveValueCache* primitiveValueCache)
 {
     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
     for (const ContentData* contentData = style->contentData(); contentData; contentData = contentData->next()) {
         if (contentData->isCounter()) {
             const CounterContent* counter = contentData->counter();
             ASSERT(counter);
-            list->append(CSSPrimitiveValue::create(counter->identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME));
+            list->append(primitiveValueCache->createValue(counter->identifier(), CSSPrimitiveValue::CSS_COUNTER_NAME));
         } else if (contentData->isImage()) {
             const StyleImage* image = contentData->image();
             ASSERT(image);
             list->append(image->cssValue());
         } else if (contentData->isText())
-            list->append(CSSPrimitiveValue::create(contentData->text(), CSSPrimitiveValue::CSS_STRING));
+            list->append(primitiveValueCache->createValue(contentData->text(), CSSPrimitiveValue::CSS_STRING));
     }
     return list.release();
 }
 
-static PassRefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, int propertyID)
+static PassRefPtr<CSSValue> counterToCSSValue(const RenderStyle* style, int propertyID, CSSPrimitiveValueCache* primitiveValueCache)
 {
     RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
     const CounterDirectiveMap* map = style->counterDirectives();
     for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) {
-        list->append(CSSPrimitiveValue::create(it->first.get(), CSSPrimitiveValue::CSS_STRING));
+        list->append(primitiveValueCache->createValue(it->first.get(), CSSPrimitiveValue::CSS_STRING));
         short number = propertyID == CSSPropertyCounterIncrement ? it->second.m_incrementValue : it->second.m_resetValue;
-        list->append(CSSPrimitiveValue::create((double)number, CSSPrimitiveValue::CSS_NUMBER));
+        list->append(primitiveValueCache->createValue((double)number, CSSPrimitiveValue::CSS_NUMBER));
     }
     return list.release();
 }
@@ -798,6 +803,8 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
 
     if (!style)
         return 0;
+    
+    CSSPrimitiveValueCache* primitiveValueCache = node->document()->cssPrimitiveValueCache().get();
 
     propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
 
@@ -806,18 +813,18 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
             break;
 
         case CSSPropertyBackgroundColor:
-            return CSSPrimitiveValue::createColor(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
+            return primitiveValueCache->createColorValue(m_allowVisitedStyle? style->visitedDependentColor(CSSPropertyBackgroundColor).rgb() : style->backgroundColor().rgb());
         case CSSPropertyBackgroundImage:
         case CSSPropertyWebkitMaskImage: {
             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskImage ? style->maskLayers() : style->backgroundLayers();
             if (!layers)
-                return CSSPrimitiveValue::createIdentifier(CSSValueNone);
+                return primitiveValueCache->createIdentifierValue(CSSValueNone);
 
             if (!layers->next()) {
                 if (layers->image())
                     return layers->image()->cssValue();
 
-                return CSSPrimitiveValue::createIdentifier(CSSValueNone);
+                return primitiveValueCache->createIdentifierValue(CSSValueNone);
             }
 
             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
@@ -825,7 +832,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
                 if (currLayer->image())
                     list->append(currLayer->image()->cssValue());
                 else
-                    list->append(CSSPrimitiveValue::createIdentifier(CSSValueNone));
+                    list->append(primitiveValueCache->createIdentifierValue(CSSValueNone));
             }
             return list.release();
         }
@@ -834,11 +841,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
         case CSSPropertyWebkitMaskSize: {
             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskSize ? style->maskLayers() : style->backgroundLayers();
             if (!layers->next())
-                return fillSizeToCSSValue(layers->size());
+                return fillSizeToCSSValue(layers->size(), primitiveValueCache);
 
             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
-                list->append(fillSizeToCSSValue(currLayer->size()));
+                list->append(fillSizeToCSSValue(currLayer->size(), primitiveValueCache));
 
             return list.release();
         }
@@ -846,11 +853,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
         case CSSPropertyWebkitMaskRepeat: {
             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskRepeat ? style->maskLayers() : style->backgroundLayers();
             if (!layers->next())
-                return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY());
+                return fillRepeatToCSSValue(layers->repeatX(), layers->repeatY(), primitiveValueCache);
 
             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
-                list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY()));
+                list->append(fillRepeatToCSSValue(currLayer->repeatX(), currLayer->repeatY(), primitiveValueCache));
 
             return list.release();
         }
@@ -858,11 +865,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
         case CSSPropertyWebkitMaskComposite: {
             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskComposite ? style->maskLayers() : style->backgroundLayers();
             if (!layers->next())
-                return CSSPrimitiveValue::create(layers->composite());
+                return primitiveValueCache->createValue(layers->composite());
 
             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
-                list->append(CSSPrimitiveValue::create(currLayer->composite()));
+                list->append(primitiveValueCache->createValue(currLayer->composite()));
 
             return list.release();
         }
@@ -870,11 +877,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
         case CSSPropertyWebkitMaskAttachment: {
             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskAttachment ? style->maskLayers() : style->backgroundLayers();
             if (!layers->next())
-                return CSSPrimitiveValue::create(layers->attachment());
+                return primitiveValueCache->createValue(layers->attachment());
 
             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
-                list->append(CSSPrimitiveValue::create(currLayer->attachment()));
+                list->append(primitiveValueCache->createValue(currLayer->attachment()));
 
             return list.release();
         }
@@ -888,13 +895,13 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
             bool isClip = propertyID == CSSPropertyBackgroundClip || propertyID == CSSPropertyWebkitBackgroundClip || propertyID == CSSPropertyWebkitMaskClip;
             if (!layers->next()) {
                 EFillBox box = isClip ? layers->clip() : layers->origin();
-                return CSSPrimitiveValue::create(box);
+                return primitiveValueCache->createValue(box);
             }
             
             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
                 EFillBox box = isClip ? currLayer->clip() : currLayer->origin();
-                list->append(CSSPrimitiveValue::create(box));
+                list->append(primitiveValueCache->createValue(box));
             }
 
             return list.release();
@@ -904,16 +911,16 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPosition ? style->maskLayers() : style->backgroundLayers();
             if (!layers->next()) {
                 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
-                list->append(CSSPrimitiveValue::create(layers->xPosition()));
-                list->append(CSSPrimitiveValue::create(layers->yPosition()));
+                list->append(primitiveValueCache->createValue(layers->xPosition()));
+                list->append(primitiveValueCache->createValue(layers->yPosition()));
                 return list.release();
             }
 
             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next()) {
                 RefPtr<CSSValueList> positionList = CSSValueList::createSpaceSeparated();
-                positionList->append(CSSPrimitiveValue::create(currLayer->xPosition()));
-                positionList->append(CSSPrimitiveValue::create(currLayer->yPosition()));
+                positionList->append(primitiveValueCache->createValue(currLayer->xPosition()));
+                positionList->append(primitiveValueCache->createValue(currLayer->yPosition()));
                 list->append(positionList);
             }
 
@@ -923,11 +930,11 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
         case CSSPropertyWebkitMaskPositionX: {
             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionX ? style->maskLayers() : style->backgroundLayers();
             if (!layers->next())
-                return CSSPrimitiveValue::create(layers->xPosition());
+                return primitiveValueCache->createValue(layers->xPosition());
 
             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
-                list->append(CSSPrimitiveValue::create(currLayer->xPosition()));
+                list->append(primitiveValueCache->createValue(currLayer->xPosition()));
 
             return list.release();
         }
@@ -935,115 +942,115 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
         case CSSPropertyWebkitMaskPositionY: {
             const FillLayer* layers = propertyID == CSSPropertyWebkitMaskPositionY ? style->maskLayers() : style->backgroundLayers();
             if (!layers->next())
-                return CSSPrimitiveValue::create(layers->yPosition());
+                return primitiveValueCache->createValue(layers->yPosition());
 
             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
             for (const FillLayer* currLayer = layers; currLayer; currLayer = currLayer->next())
-                list->append(CSSPrimitiveValue::create(currLayer->yPosition()));
+                list->append(primitiveValueCache->createValue(currLayer->yPosition()));
 
             return list.release();
         }
         case CSSPropertyBorderCollapse:
             if (style->borderCollapse())
-                return CSSPrimitiveValue::createIdentifier(CSSValueCollapse);
-            return CSSPrimitiveValue::createIdentifier(CSSValueSeparate);
+                return primitiveValueCache->createIdentifierValue(CSSValueCollapse);
+            return primitiveValueCache->createIdentifierValue(CSSValueSeparate);
         case CSSPropertyBorderSpacing: {
             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
-            list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get()));
-            list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get()));
+            list->append(zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get(), primitiveValueCache));
+            list->append(zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get(), primitiveValueCache));
             return list.release();
         }  
         case CSSPropertyWebkitBorderHorizontalSpacing:
-            return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get());
+            return zoomAdjustedPixelValue(style->horizontalBorderSpacing(), style.get(), primitiveValueCache);
         case CSSPropertyWebkitBorderVerticalSpacing:
-            return zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get());
+            return zoomAdjustedPixelValue(style->verticalBorderSpacing(), style.get(), primitiveValueCache);
         case CSSPropertyBorderTopColor:
-            return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style.get(), style->borderTopColor());
+            return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyBorderTopColor).rgb()) : currentColorOrValidColor(style.get(), style->borderTopColor());
         case CSSPropertyBorderRightColor:
-            return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style.get(), style->borderRightColor());
+            return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyBorderRightColor).rgb()) : currentColorOrValidColor(style.get(), style->borderRightColor());
         case CSSPropertyBorderBottomColor:
-            return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style.get(), style->borderBottomColor());
+            return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyBorderBottomColor).rgb()) : currentColorOrValidColor(style.get(), style->borderBottomColor());
         case CSSPropertyBorderLeftColor:
-            return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style.get(), style->borderLeftColor());
+            return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyBorderLeftColor).rgb()) : currentColorOrValidColor(style.get(), style->borderLeftColor());
         case CSSPropertyBorderTopStyle:
-            return CSSPrimitiveValue::create(style->borderTopStyle());
+            return primitiveValueCache->createValue(style->borderTopStyle());
         case CSSPropertyBorderRightStyle:
-            return CSSPrimitiveValue::create(style->borderRightStyle());
+            return primitiveValueCache->createValue(style->borderRightStyle());
         case CSSPropertyBorderBottomStyle:
-            return CSSPrimitiveValue::create(style->borderBottomStyle());
+            return primitiveValueCache->createValue(style->borderBottomStyle());
         case CSSPropertyBorderLeftStyle:
-            return CSSPrimitiveValue::create(style->borderLeftStyle());
+            return primitiveValueCache->createValue(style->borderLeftStyle());
         case CSSPropertyBorderTopWidth:
-            return zoomAdjustedPixelValue(style->borderTopWidth(), style.get());
+            return zoomAdjustedPixelValue(style->borderTopWidth(), style.get(), primitiveValueCache);
         case CSSPropertyBorderRightWidth:
-            return zoomAdjustedPixelValue(style->borderRightWidth(), style.get());
+            return zoomAdjustedPixelValue(style->borderRightWidth(), style.get(), primitiveValueCache);
         case CSSPropertyBorderBottomWidth:
-            return zoomAdjustedPixelValue(style->borderBottomWidth(), style.get());
+            return zoomAdjustedPixelValue(style->borderBottomWidth(), style.get(), primitiveValueCache);
         case CSSPropertyBorderLeftWidth:
-            return zoomAdjustedPixelValue(style->borderLeftWidth(), style.get());
+            return zoomAdjustedPixelValue(style->borderLeftWidth(), style.get(), primitiveValueCache);
         case CSSPropertyBottom:
-            return getPositionOffsetValue(style.get(), CSSPropertyBottom);
+            return getPositionOffsetValue(style.get(), CSSPropertyBottom, primitiveValueCache);
         case CSSPropertyWebkitBoxAlign:
-            return CSSPrimitiveValue::create(style->boxAlign());
+            return primitiveValueCache->createValue(style->boxAlign());
         case CSSPropertyWebkitBoxDirection:
-            return CSSPrimitiveValue::create(style->boxDirection());
+            return primitiveValueCache->createValue(style->boxDirection());
         case CSSPropertyWebkitBoxFlex:
-            return CSSPrimitiveValue::create(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
+            return primitiveValueCache->createValue(style->boxFlex(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyWebkitBoxFlexGroup:
-            return CSSPrimitiveValue::create(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
+            return primitiveValueCache->createValue(style->boxFlexGroup(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyWebkitBoxLines:
-            return CSSPrimitiveValue::create(style->boxLines());
+            return primitiveValueCache->createValue(style->boxLines());
         case CSSPropertyWebkitBoxOrdinalGroup:
-            return CSSPrimitiveValue::create(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
+            return primitiveValueCache->createValue(style->boxOrdinalGroup(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyWebkitBoxOrient:
-            return CSSPrimitiveValue::create(style->boxOrient());
+            return primitiveValueCache->createValue(style->boxOrient());
         case CSSPropertyWebkitBoxPack: {
             EBoxAlignment boxPack = style->boxPack();
             ASSERT(boxPack != BSTRETCH);
             ASSERT(boxPack != BBASELINE);
             if (boxPack == BJUSTIFY || boxPack== BBASELINE)
                 return 0;
-            return CSSPrimitiveValue::create(boxPack);
+            return primitiveValueCache->createValue(boxPack);
         }
         case CSSPropertyWebkitBoxReflect:
-            return valueForReflection(style->boxReflect(), style.get());
+            return valueForReflection(style->boxReflect(), style.get(), primitiveValueCache);
         case CSSPropertyBoxShadow:
         case CSSPropertyWebkitBoxShadow:
             return valueForShadow(style->boxShadow(), propertyID, style.get());
         case CSSPropertyCaptionSide:
-            return CSSPrimitiveValue::create(style->captionSide());
+            return primitiveValueCache->createValue(style->captionSide());
         case CSSPropertyClear:
-            return CSSPrimitiveValue::create(style->clear());
+            return primitiveValueCache->createValue(style->clear());
         case CSSPropertyColor:
-            return CSSPrimitiveValue::createColor(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
+            return primitiveValueCache->createColorValue(m_allowVisitedStyle ? style->visitedDependentColor(CSSPropertyColor).rgb() : style->color().rgb());
         case CSSPropertyWebkitColumnCount:
             if (style->hasAutoColumnCount())
-                return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
-            return CSSPrimitiveValue::create(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
+                return primitiveValueCache->createIdentifierValue(CSSValueAuto);
+            return primitiveValueCache->createValue(style->columnCount(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyWebkitColumnGap:
             if (style->hasNormalColumnGap())
-                return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
-            return CSSPrimitiveValue::create(style->columnGap(), CSSPrimitiveValue::CSS_NUMBER);
+                return primitiveValueCache->createIdentifierValue(CSSValueNormal);
+            return primitiveValueCache->createValue(style->columnGap(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyWebkitColumnRuleColor:
-            return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor());
+            return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->columnRuleColor());
         case CSSPropertyWebkitColumnRuleStyle:
-            return CSSPrimitiveValue::create(style->columnRuleStyle());
+            return primitiveValueCache->createValue(style->columnRuleStyle());
         case CSSPropertyWebkitColumnRuleWidth:
-            return zoomAdjustedPixelValue(style->columnRuleWidth(), style.get());
+            return zoomAdjustedPixelValue(style->columnRuleWidth(), style.get(), primitiveValueCache);
         case CSSPropertyWebkitColumnSpan:
             if (style->columnSpan())
-                return CSSPrimitiveValue::createIdentifier(CSSValueAll);
-            return CSSPrimitiveValue::create(1, CSSPrimitiveValue::CSS_NUMBER);
+                return primitiveValueCache->createIdentifierValue(CSSValueAll);
+            return primitiveValueCache->createValue(1, CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyWebkitColumnBreakAfter:
-            return CSSPrimitiveValue::create(style->columnBreakAfter());
+            return primitiveValueCache->createValue(style->columnBreakAfter());
         case CSSPropertyWebkitColumnBreakBefore:
-            return CSSPrimitiveValue::create(style->columnBreakBefore());
+            return primitiveValueCache->createValue(style->columnBreakBefore());
         case CSSPropertyWebkitColumnBreakInside:
-            return CSSPrimitiveValue::create(style->columnBreakInside());
+            return primitiveValueCache->createValue(style->columnBreakInside());
         case CSSPropertyWebkitColumnWidth:
             if (style->hasAutoColumnWidth())
-                return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
-            return CSSPrimitiveValue::create(style->columnWidth(), CSSPrimitiveValue::CSS_NUMBER);
+                return primitiveValueCache->createIdentifierValue(CSSValueAuto);
+            return primitiveValueCache->createValue(style->columnWidth(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyCursor: {
             RefPtr<CSSValueList> list;
             CursorList* cursors = style->cursors();
@@ -1053,7 +1060,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
                     if (StyleImage* image = cursors->at(i).image())
                         list->append(image->cssValue());
             }
-            RefPtr<CSSValue> value = CSSPrimitiveValue::create(style->cursor());
+            RefPtr<CSSValue> value = primitiveValueCache->createValue(style->cursor());
             if (list) {
                 list->append(value);
                 return list.release();
@@ -1061,69 +1068,69 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
             return value.release();
         }
         case CSSPropertyDirection:
-            return CSSPrimitiveValue::create(style->direction());
+            return primitiveValueCache->createValue(style->direction());
         case CSSPropertyDisplay:
-            return CSSPrimitiveValue::create(style->display());
+            return primitiveValueCache->createValue(style->display());
         case CSSPropertyEmptyCells:
-            return CSSPrimitiveValue::create(style->emptyCells());
+            return primitiveValueCache->createValue(style->emptyCells());
         case CSSPropertyFloat:
-            return CSSPrimitiveValue::create(style->floating());
+            return primitiveValueCache->createValue(style->floating());
         case CSSPropertyFontFamily: {
             const FontFamily& firstFamily = style->fontDescription().family();
             if (!firstFamily.next())
-                return valueForFamily(firstFamily.family());
+                return valueForFamily(firstFamily.family(), primitiveValueCache);
             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
             for (const FontFamily* family = &firstFamily; family; family = family->next())
-                list->append(valueForFamily(family->family()));
+                list->append(valueForFamily(family->family(), primitiveValueCache));
             return list.release();
         }
         case CSSPropertyFontSize:
-            return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style.get());
+            return zoomAdjustedPixelValue(style->fontDescription().computedPixelSize(), style.get(), primitiveValueCache);
         case CSSPropertyFontStyle:
             if (style->fontDescription().italic())
-                return CSSPrimitiveValue::createIdentifier(CSSValueItalic);
-            return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
+                return primitiveValueCache->createIdentifierValue(CSSValueItalic);
+            return primitiveValueCache->createIdentifierValue(CSSValueNormal);
         case CSSPropertyFontVariant:
             if (style->fontDescription().smallCaps())
-                return CSSPrimitiveValue::createIdentifier(CSSValueSmallCaps);
-            return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
+                return primitiveValueCache->createIdentifierValue(CSSValueSmallCaps);
+            return primitiveValueCache->createIdentifierValue(CSSValueNormal);
         case CSSPropertyFontWeight:
             switch (style->fontDescription().weight()) {
                 case FontWeight100:
-                    return CSSPrimitiveValue::createIdentifier(CSSValue100);
+                    return primitiveValueCache->createIdentifierValue(CSSValue100);
                 case FontWeight200:
-                    return CSSPrimitiveValue::createIdentifier(CSSValue200);
+                    return primitiveValueCache->createIdentifierValue(CSSValue200);
                 case FontWeight300:
-                    return CSSPrimitiveValue::createIdentifier(CSSValue300);
+                    return primitiveValueCache->createIdentifierValue(CSSValue300);
                 case FontWeightNormal:
-                    return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
+                    return primitiveValueCache->createIdentifierValue(CSSValueNormal);
                 case FontWeight500:
-                    return CSSPrimitiveValue::createIdentifier(CSSValue500);
+                    return primitiveValueCache->createIdentifierValue(CSSValue500);
                 case FontWeight600:
-                    return CSSPrimitiveValue::createIdentifier(CSSValue600);
+                    return primitiveValueCache->createIdentifierValue(CSSValue600);
                 case FontWeightBold:
-                    return CSSPrimitiveValue::createIdentifier(CSSValueBold);
+                    return primitiveValueCache->createIdentifierValue(CSSValueBold);
                 case FontWeight800:
-                    return CSSPrimitiveValue::createIdentifier(CSSValue800);
+                    return primitiveValueCache->createIdentifierValue(CSSValue800);
                 case FontWeight900:
-                    return CSSPrimitiveValue::createIdentifier(CSSValue900);
+                    return primitiveValueCache->createIdentifierValue(CSSValue900);
             }
             ASSERT_NOT_REACHED();
-            return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
+            return primitiveValueCache->createIdentifierValue(CSSValueNormal);
         case CSSPropertyHeight:
             if (renderer)
-                return zoomAdjustedPixelValue(sizingBox(renderer).height(), style.get());
-            return zoomAdjustedPixelValueForLength(style->height(), style.get());
+                return zoomAdjustedPixelValue(sizingBox(renderer).height(), style.get(), primitiveValueCache);
+            return zoomAdjustedPixelValueForLength(style->height(), style.get(), primitiveValueCache);
         case CSSPropertyWebkitHighlight:
             if (style->highlight() == nullAtom)
-                return CSSPrimitiveValue::createIdentifier(CSSValueNone);
-            return CSSPrimitiveValue::create(style->highlight(), CSSPrimitiveValue::CSS_STRING);
+                return primitiveValueCache->createIdentifierValue(CSSValueNone);
+            return primitiveValueCache->createValue(style->highlight(), CSSPrimitiveValue::CSS_STRING);
         case CSSPropertyWebkitHyphens:
-            return CSSPrimitiveValue::create(style->hyphens());
+            return primitiveValueCache->createValue(style->hyphens());
         case CSSPropertyWebkitHyphenateCharacter:
             if (style->hyphenationString().isNull())
-                return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
-            return CSSPrimitiveValue::create(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING);
+                return primitiveValueCache->createIdentifierValue(CSSValueAuto);
+            return primitiveValueCache->createValue(style->hyphenationString(), CSSPrimitiveValue::CSS_STRING);
         case CSSPropertyWebkitHyphenateLimitAfter:
             if (style->hyphenationLimitAfter() < 0)
                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
@@ -1134,165 +1141,165 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
             return CSSPrimitiveValue::create(style->hyphenationLimitBefore(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyWebkitBorderFit:
             if (style->borderFit() == BorderFitBorder)
-                return CSSPrimitiveValue::createIdentifier(CSSValueBorder);
-            return CSSPrimitiveValue::createIdentifier(CSSValueLines);
+                return primitiveValueCache->createIdentifierValue(CSSValueBorder);
+            return primitiveValueCache->createIdentifierValue(CSSValueLines);
         case CSSPropertyLeft:
-            return getPositionOffsetValue(style.get(), CSSPropertyLeft);
+            return getPositionOffsetValue(style.get(), CSSPropertyLeft, primitiveValueCache);
         case CSSPropertyLetterSpacing:
             if (!style->letterSpacing())
-                return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
-            return zoomAdjustedPixelValue(style->letterSpacing(), style.get());
+                return primitiveValueCache->createIdentifierValue(CSSValueNormal);
+            return zoomAdjustedPixelValue(style->letterSpacing(), style.get(), primitiveValueCache);
         case CSSPropertyWebkitLineClamp:
             if (style->lineClamp().isNone())
-                return CSSPrimitiveValue::createIdentifier(CSSValueNone);
-            return CSSPrimitiveValue::create(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
+                return primitiveValueCache->createIdentifierValue(CSSValueNone);
+            return primitiveValueCache->createValue(style->lineClamp().value(), style->lineClamp().isPercentage() ? CSSPrimitiveValue::CSS_PERCENTAGE : CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyLineHeight: {
             Length length = style->lineHeight();
             if (length.isNegative())
-                return CSSPrimitiveValue::createIdentifier(CSSValueNormal);
+                return primitiveValueCache->createIdentifierValue(CSSValueNormal);
             if (length.isPercent())
                 // This is imperfect, because it doesn't include the zoom factor and the real computation
                 // for how high to be in pixels does include things like minimum font size and the zoom factor.
                 // On the other hand, since font-size doesn't include the zoom factor, we really can't do
                 // that here either.
-                return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style->fontDescription().specifiedSize()) / 100, style.get());
-            return zoomAdjustedPixelValue(length.value(), style.get());
+                return zoomAdjustedPixelValue(static_cast<int>(length.percent() * style->fontDescription().specifiedSize()) / 100, style.get(), primitiveValueCache);
+            return zoomAdjustedPixelValue(length.value(), style.get(), primitiveValueCache);
         }
         case CSSPropertyListStyleImage:
             if (style->listStyleImage())
                 return style->listStyleImage()->cssValue();
-            return CSSPrimitiveValue::createIdentifier(CSSValueNone);
+            return primitiveValueCache->createIdentifierValue(CSSValueNone);
         case CSSPropertyListStylePosition:
-            return CSSPrimitiveValue::create(style->listStylePosition());
+            return primitiveValueCache->createValue(style->listStylePosition());
         case CSSPropertyListStyleType:
-            return CSSPrimitiveValue::create(style->listStyleType());
+            return primitiveValueCache->createValue(style->listStyleType());
         case CSSPropertyWebkitLocale:
             if (style->locale().isNull())
-                return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
-            return CSSPrimitiveValue::create(style->locale(), CSSPrimitiveValue::CSS_STRING);
+                return primitiveValueCache->createIdentifierValue(CSSValueAuto);
+            return primitiveValueCache->createValue(style->locale(), CSSPrimitiveValue::CSS_STRING);
         case CSSPropertyMarginTop: {
             Length marginTop = style->marginTop();
             if (marginTop.isPercent())
-                return CSSPrimitiveValue::create(marginTop);
-            return zoomAdjustedPixelValue(marginTop.value(), style.get());
+                return primitiveValueCache->createValue(marginTop);
+            return zoomAdjustedPixelValue(marginTop.value(), style.get(), primitiveValueCache);
         }
         case CSSPropertyMarginRight: {
             Length marginRight = style->marginRight();
             if (marginRight.isPercent())
-                return CSSPrimitiveValue::create(marginRight);
-            return zoomAdjustedPixelValue(marginRight.value(), style.get());
+                return primitiveValueCache->createValue(marginRight);
+            return zoomAdjustedPixelValue(marginRight.value(), style.get(), primitiveValueCache);
         }
         case CSSPropertyMarginBottom: {
             Length marginBottom = style->marginBottom();
             if (marginBottom.isPercent())
-                return CSSPrimitiveValue::create(marginBottom);
-            return zoomAdjustedPixelValue(marginBottom.value(), style.get());
+                return primitiveValueCache->createValue(marginBottom);
+            return zoomAdjustedPixelValue(marginBottom.value(), style.get(), primitiveValueCache);
         }
         case CSSPropertyMarginLeft: {
             Length marginLeft = style->marginLeft();
             if (marginLeft.isPercent())
-                return CSSPrimitiveValue::create(marginLeft);
-            return zoomAdjustedPixelValue(marginLeft.value(), style.get());
+                return primitiveValueCache->createValue(marginLeft);
+            return zoomAdjustedPixelValue(marginLeft.value(), style.get(), primitiveValueCache);
         }
         case CSSPropertyWebkitMarqueeDirection:
-            return CSSPrimitiveValue::create(style->marqueeDirection());
+            return primitiveValueCache->createValue(style->marqueeDirection());
         case CSSPropertyWebkitMarqueeIncrement:
-            return CSSPrimitiveValue::create(style->marqueeIncrement());
+            return primitiveValueCache->createValue(style->marqueeIncrement());
         case CSSPropertyWebkitMarqueeRepetition:
             if (style->marqueeLoopCount() < 0)
-                return CSSPrimitiveValue::createIdentifier(CSSValueInfinite);
-            return CSSPrimitiveValue::create(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
+                return primitiveValueCache->createIdentifierValue(CSSValueInfinite);
+            return primitiveValueCache->createValue(style->marqueeLoopCount(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyWebkitMarqueeStyle:
-            return CSSPrimitiveValue::create(style->marqueeBehavior());
+            return primitiveValueCache->createValue(style->marqueeBehavior());
         case CSSPropertyWebkitUserModify:
-            return CSSPrimitiveValue::create(style->userModify());
+            return primitiveValueCache->createValue(style->userModify());
         case CSSPropertyMaxHeight: {
             const Length& maxHeight = style->maxHeight();
             if (maxHeight.isFixed() && maxHeight.value() == undefinedLength)
-                return CSSPrimitiveValue::createIdentifier(CSSValueNone);
-            return CSSPrimitiveValue::create(maxHeight);
+                return primitiveValueCache->createIdentifierValue(CSSValueNone);
+            return primitiveValueCache->createValue(maxHeight);
         }
         case CSSPropertyMaxWidth: {
             const Length& maxWidth = style->maxWidth();
             if (maxWidth.isFixed() && maxWidth.value() == undefinedLength)
-                return CSSPrimitiveValue::createIdentifier(CSSValueNone);
-            return CSSPrimitiveValue::create(maxWidth);
+                return primitiveValueCache->createIdentifierValue(CSSValueNone);
+            return primitiveValueCache->createValue(maxWidth);
         }
         case CSSPropertyMinHeight:
-            return CSSPrimitiveValue::create(style->minHeight());
+            return primitiveValueCache->createValue(style->minHeight());
         case CSSPropertyMinWidth:
-            return CSSPrimitiveValue::create(style->minWidth());
+            return primitiveValueCache->createValue(style->minWidth());
         case CSSPropertyOpacity:
-            return CSSPrimitiveValue::create(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
+            return primitiveValueCache->createValue(style->opacity(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyOrphans:
-            return CSSPrimitiveValue::create(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
+            return primitiveValueCache->createValue(style->orphans(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyOutlineColor:
-            return m_allowVisitedStyle ? CSSPrimitiveValue::createColor(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->outlineColor());
+            return m_allowVisitedStyle ? primitiveValueCache->createColorValue(style->visitedDependentColor(CSSPropertyOutlineColor).rgb()) : currentColorOrValidColor(style.get(), style->outlineColor());
         case CSSPropertyOutlineOffset:
-            return zoomAdjustedPixelValue(style->outlineOffset(), style.get());
+            return zoomAdjustedPixelValue(style->outlineOffset(), style.get(), primitiveValueCache);
         case CSSPropertyOutlineStyle:
             if (style->outlineStyleIsAuto())
-                return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
-            return CSSPrimitiveValue::create(style->outlineStyle());
+                return primitiveValueCache->createIdentifierValue(CSSValueAuto);
+            return primitiveValueCache->createValue(style->outlineStyle());
         case CSSPropertyOutlineWidth:
-            return zoomAdjustedPixelValue(style->outlineWidth(), style.get());
+            return zoomAdjustedPixelValue(style->outlineWidth(), style.get(), primitiveValueCache);
         case CSSPropertyOverflow:
-            return CSSPrimitiveValue::create(max(style->overflowX(), style->overflowY()));
+            return primitiveValueCache->createValue(max(style->overflowX(), style->overflowY()));
         case CSSPropertyOverflowX:
-            return CSSPrimitiveValue::create(style->overflowX());
+            return primitiveValueCache->createValue(style->overflowX());
         case CSSPropertyOverflowY:
-            return CSSPrimitiveValue::create(style->overflowY());
+            return primitiveValueCache->createValue(style->overflowY());
         case CSSPropertyPaddingTop:
             if (renderer && renderer->isBox())
-                return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingTop(false), style.get());
-            return CSSPrimitiveValue::create(style->paddingTop());
+                return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingTop(false), style.get(), primitiveValueCache);
+            return primitiveValueCache->createValue(style->paddingTop());
         case CSSPropertyPaddingRight:
             if (renderer && renderer->isBox())
-                return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingRight(false), style.get());
-            return CSSPrimitiveValue::create(style->paddingRight());
+                return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingRight(false), style.get(), primitiveValueCache);
+            return primitiveValueCache->createValue(style->paddingRight());
         case CSSPropertyPaddingBottom:
             if (renderer && renderer->isBox())
-                return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingBottom(false), style.get());
-            return CSSPrimitiveValue::create(style->paddingBottom());
+                return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingBottom(false), style.get(), primitiveValueCache);
+            return primitiveValueCache->createValue(style->paddingBottom());
         case CSSPropertyPaddingLeft:
             if (renderer && renderer->isBox())
-                return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingLeft(false), style.get());
-            return CSSPrimitiveValue::create(style->paddingLeft());
+                return zoomAdjustedPixelValue(toRenderBox(renderer)->paddingLeft(false), style.get(), primitiveValueCache);
+            return primitiveValueCache->createValue(style->paddingLeft());
         case CSSPropertyPageBreakAfter:
-            return CSSPrimitiveValue::create(style->pageBreakAfter());
+            return primitiveValueCache->createValue(style->pageBreakAfter());
         case CSSPropertyPageBreakBefore:
-            return CSSPrimitiveValue::create(style->pageBreakBefore());
+            return primitiveValueCache->createValue(style->pageBreakBefore());
         case CSSPropertyPageBreakInside: {
             EPageBreak pageBreak = style->pageBreakInside();
             ASSERT(pageBreak != PBALWAYS);
             if (pageBreak == PBALWAYS)
                 return 0;
-            return CSSPrimitiveValue::create(style->pageBreakInside());
+            return primitiveValueCache->createValue(style->pageBreakInside());
         }
         case CSSPropertyPosition:
-            return CSSPrimitiveValue::create(style->position());
+            return primitiveValueCache->createValue(style->position());
         case CSSPropertyRight:
-            return getPositionOffsetValue(style.get(), CSSPropertyRight);
+            return getPositionOffsetValue(style.get(), CSSPropertyRight, primitiveValueCache);
         case CSSPropertyTableLayout:
-            return CSSPrimitiveValue::create(style->tableLayout());
+            return primitiveValueCache->createValue(style->tableLayout());
         case CSSPropertyTextAlign:
-            return CSSPrimitiveValue::create(style->textAlign());
+            return primitiveValueCache->createValue(style->textAlign());
         case CSSPropertyTextDecoration:
-            return renderTextDecorationFlagsToCSSValue(style->textDecoration());
+            return renderTextDecorationFlagsToCSSValue(style->textDecoration(), primitiveValueCache);
         case CSSPropertyWebkitTextDecorationsInEffect:
-            return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect());
+            return renderTextDecorationFlagsToCSSValue(style->textDecorationsInEffect(), primitiveValueCache);
         case CSSPropertyWebkitTextFillColor:
             return currentColorOrValidColor(style.get(), style->textFillColor());
         case CSSPropertyWebkitTextEmphasisColor:
             return currentColorOrValidColor(style.get(), style->textEmphasisColor());
         case CSSPropertyWebkitTextEmphasisPosition:
-            return CSSPrimitiveValue::create(style->textEmphasisPosition());
+            return primitiveValueCache->createValue(style->textEmphasisPosition());
         case CSSPropertyWebkitTextEmphasisStyle:
             switch (style->textEmphasisMark()) {
             case TextEmphasisMarkNone:
-                return CSSPrimitiveValue::createIdentifier(CSSValueNone);
+                return primitiveValueCache->createIdentifierValue(CSSValueNone);
             case TextEmphasisMarkCustom:
-                return CSSPrimitiveValue::create(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
+                return primitiveValueCache->createValue(style->textEmphasisCustomMark(), CSSPrimitiveValue::CSS_STRING);
             case TextEmphasisMarkAuto:
                 ASSERT_NOT_REACHED();
                 // Fall through
@@ -1302,105 +1309,105 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
             case TextEmphasisMarkTriangle:
             case TextEmphasisMarkSesame: {
                 RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
-                list->append(CSSPrimitiveValue::create(style->textEmphasisFill()));
-                list->append(CSSPrimitiveValue::create(style->textEmphasisMark()));
+                list->append(primitiveValueCache->createValue(style->textEmphasisFill()));
+                list->append(primitiveValueCache->createValue(style->textEmphasisMark()));
                 return list.release();
             }
             }
         case CSSPropertyTextIndent:
-            return CSSPrimitiveValue::create(style->textIndent());
+            return primitiveValueCache->createValue(style->textIndent());
         case CSSPropertyTextShadow:
             return valueForShadow(style->textShadow(), propertyID, style.get());
         case CSSPropertyTextRendering:
-            return CSSPrimitiveValue::create(style->fontDescription().textRenderingMode());
+            return primitiveValueCache->createValue(style->fontDescription().textRenderingMode());
         case CSSPropertyTextOverflow:
             if (style->textOverflow())
-                return CSSPrimitiveValue::createIdentifier(CSSValueEllipsis);
-            return CSSPrimitiveValue::createIdentifier(CSSValueClip);
+                return primitiveValueCache->createIdentifierValue(CSSValueEllipsis);
+            return primitiveValueCache->createIdentifierValue(CSSValueClip);
         case CSSPropertyWebkitTextSecurity:
-            return CSSPrimitiveValue::create(style->textSecurity());
+            return primitiveValueCache->createValue(style->textSecurity());
         case CSSPropertyWebkitTextSizeAdjust:
             if (style->textSizeAdjust())
-                return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
-            return CSSPrimitiveValue::createIdentifier(CSSValueNone);
+                return primitiveValueCache->createIdentifierValue(CSSValueAuto);
+            return primitiveValueCache->createIdentifierValue(CSSValueNone);
         case CSSPropertyWebkitTextStrokeColor:
             return currentColorOrValidColor(style.get(), style->textStrokeColor());
         case CSSPropertyWebkitTextStrokeWidth:
-            return zoomAdjustedPixelValue(style->textStrokeWidth(), style.get());
+            return zoomAdjustedPixelValue(style->textStrokeWidth(), style.get(), primitiveValueCache);
         case CSSPropertyTextTransform:
-            return CSSPrimitiveValue::create(style->textTransform());
+            return primitiveValueCache->createValue(style->textTransform());
         case CSSPropertyTop:
-            return getPositionOffsetValue(style.get(), CSSPropertyTop);
+            return getPositionOffsetValue(style.get(), CSSPropertyTop, primitiveValueCache);
         case CSSPropertyUnicodeBidi:
-            return CSSPrimitiveValue::create(style->unicodeBidi());
+            return primitiveValueCache->createValue(style->unicodeBidi());
         case CSSPropertyVerticalAlign:
             switch (style->verticalAlign()) {
                 case BASELINE:
-                    return CSSPrimitiveValue::createIdentifier(CSSValueBaseline);
+                    return primitiveValueCache->createIdentifierValue(CSSValueBaseline);
                 case MIDDLE:
-                    return CSSPrimitiveValue::createIdentifier(CSSValueMiddle);
+                    return primitiveValueCache->createIdentifierValue(CSSValueMiddle);
                 case SUB:
-                    return CSSPrimitiveValue::createIdentifier(CSSValueSub);
+                    return primitiveValueCache->createIdentifierValue(CSSValueSub);
                 case SUPER:
-                    return CSSPrimitiveValue::createIdentifier(CSSValueSuper);
+                    return primitiveValueCache->createIdentifierValue(CSSValueSuper);
                 case TEXT_TOP:
-                    return CSSPrimitiveValue::createIdentifier(CSSValueTextTop);
+                    return primitiveValueCache->createIdentifierValue(CSSValueTextTop);
                 case TEXT_BOTTOM:
-                    return CSSPrimitiveValue::createIdentifier(CSSValueTextBottom);
+                    return primitiveValueCache->createIdentifierValue(CSSValueTextBottom);
                 case TOP:
-                    return CSSPrimitiveValue::createIdentifier(CSSValueTop);
+                    return primitiveValueCache->createIdentifierValue(CSSValueTop);
                 case BOTTOM:
-                    return CSSPrimitiveValue::createIdentifier(CSSValueBottom);
+                    return primitiveValueCache->createIdentifierValue(CSSValueBottom);
                 case BASELINE_MIDDLE:
-                    return CSSPrimitiveValue::createIdentifier(CSSValueWebkitBaselineMiddle);
+                    return primitiveValueCache->createIdentifierValue(CSSValueWebkitBaselineMiddle);
                 case LENGTH:
-                    return CSSPrimitiveValue::create(style->verticalAlignLength());
+                    return primitiveValueCache->createValue(style->verticalAlignLength());
             }
             ASSERT_NOT_REACHED();
             return 0;
         case CSSPropertyVisibility:
-            return CSSPrimitiveValue::create(style->visibility());
+            return primitiveValueCache->createValue(style->visibility());
         case CSSPropertyWhiteSpace:
-            return CSSPrimitiveValue::create(style->whiteSpace());
+            return primitiveValueCache->createValue(style->whiteSpace());
         case CSSPropertyWidows:
-            return CSSPrimitiveValue::create(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
+            return primitiveValueCache->createValue(style->widows(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyWidth:
             if (renderer)
-                return zoomAdjustedPixelValue(sizingBox(renderer).width(), style.get());
-            return zoomAdjustedPixelValueForLength(style->width(), style.get());
+                return zoomAdjustedPixelValue(sizingBox(renderer).width(), style.get(), primitiveValueCache);
+            return zoomAdjustedPixelValueForLength(style->width(), style.get(), primitiveValueCache);
         case CSSPropertyWordBreak:
-            return CSSPrimitiveValue::create(style->wordBreak());
+            return primitiveValueCache->createValue(style->wordBreak());
         case CSSPropertyWordSpacing:
-            return zoomAdjustedPixelValue(style->wordSpacing(), style.get());
+            return zoomAdjustedPixelValue(style->wordSpacing(), style.get(), primitiveValueCache);
         case CSSPropertyWordWrap:
-            return CSSPrimitiveValue::create(style->wordWrap());
+            return primitiveValueCache->createValue(style->wordWrap());
         case CSSPropertyWebkitLineBreak:
-            return CSSPrimitiveValue::create(style->khtmlLineBreak());
+            return primitiveValueCache->createValue(style->khtmlLineBreak());
         case CSSPropertyWebkitNbspMode:
-            return CSSPrimitiveValue::create(style->nbspMode());
+            return primitiveValueCache->createValue(style->nbspMode());
         case CSSPropertyWebkitMatchNearestMailBlockquoteColor:
-            return CSSPrimitiveValue::create(style->matchNearestMailBlockquoteColor());
+            return primitiveValueCache->createValue(style->matchNearestMailBlockquoteColor());
         case CSSPropertyResize:
-            return CSSPrimitiveValue::create(style->resize());
+            return primitiveValueCache->createValue(style->resize());
         case CSSPropertyWebkitFontSmoothing:
-            return CSSPrimitiveValue::create(style->fontDescription().fontSmoothing());
+            return primitiveValueCache->createValue(style->fontDescription().fontSmoothing());
         case CSSPropertyZIndex:
             if (style->hasAutoZIndex())
-                return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
-            return CSSPrimitiveValue::create(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
+                return primitiveValueCache->createIdentifierValue(CSSValueAuto);
+            return primitiveValueCache->createValue(style->zIndex(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyZoom:
-            return CSSPrimitiveValue::create(style->zoom(), CSSPrimitiveValue::CSS_NUMBER);
+            return primitiveValueCache->createValue(style->zoom(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyBoxSizing:
             if (style->boxSizing() == CONTENT_BOX)
-                return CSSPrimitiveValue::createIdentifier(CSSValueContentBox);
-            return CSSPrimitiveValue::createIdentifier(CSSValueBorderBox);
+                return primitiveValueCache->createIdentifierValue(CSSValueContentBox);
+            return primitiveValueCache->createIdentifierValue(CSSValueBorderBox);
 #if ENABLE(DASHBOARD_SUPPORT)
         case CSSPropertyWebkitDashboardRegion:
         {
             const Vector<StyleDashboardRegion>& regions = style->dashboardRegions();
             unsigned count = regions.size();
             if (count == 1 && regions[0].type == StyleDashboardRegion::None)
-                return CSSPrimitiveValue::createIdentifier(CSSValueNone);
+                return primitiveValueCache->createIdentifierValue(CSSValueNone);
 
             RefPtr<DashboardRegion> firstRegion;
             DashboardRegion* previousRegion = 0;
@@ -1410,10 +1417,10 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
 
                 region->m_label = styleRegion.label;
                 LengthBox offset = styleRegion.offset;
-                region->setTop(zoomAdjustedPixelValue(offset.top().value(), style.get()));
-                region->setRight(zoomAdjustedPixelValue(offset.right().value(), style.get()));
-                region->setBottom(zoomAdjustedPixelValue(offset.bottom().value(), style.get()));
-                region->setLeft(zoomAdjustedPixelValue(offset.left().value(), style.get()));
+                region->setTop(zoomAdjustedPixelValue(offset.top().value(), style.get(), primitiveValueCache));
+                region->setRight(zoomAdjustedPixelValue(offset.right().value(), style.get(), primitiveValueCache));
+                region->setBottom(zoomAdjustedPixelValue(offset.bottom().value(), style.get(), primitiveValueCache));
+                region->setLeft(zoomAdjustedPixelValue(offset.left().value(), style.get(), primitiveValueCache));
                 region->m_isRectangle = (styleRegion.type == StyleDashboardRegion::Rectangle);
                 region->m_isCircle = (styleRegion.type == StyleDashboardRegion::Circle);
 
@@ -1423,27 +1430,27 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
                     firstRegion = region;
                 previousRegion = region.get();
             }
-            return CSSPrimitiveValue::create(firstRegion.release());
+            return primitiveValueCache->createValue(firstRegion.release());
         }
 #endif
         case CSSPropertyWebkitAnimationDelay:
-            return getDelayValue(style->animations());
+            return getDelayValue(style->animations(), primitiveValueCache);
         case CSSPropertyWebkitAnimationDirection: {
             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
             const AnimationList* t = style->animations();
             if (t) {
                 for (size_t i = 0; i < t->size(); ++i) {
                     if (t->animation(i)->direction())
-                        list->append(CSSPrimitiveValue::createIdentifier(CSSValueAlternate));
+                        list->append(primitiveValueCache->createIdentifierValue(CSSValueAlternate));
                     else
-                        list->append(CSSPrimitiveValue::createIdentifier(CSSValueNormal));
+                        list->append(primitiveValueCache->createIdentifierValue(CSSValueNormal));
                 }
             } else
-                list->append(CSSPrimitiveValue::createIdentifier(CSSValueNormal));
+                list->append(primitiveValueCache->createIdentifierValue(CSSValueNormal));
             return list.release();
         }
         case CSSPropertyWebkitAnimationDuration:
-            return getDurationValue(style->animations());
+            return getDurationValue(style->animations(), primitiveValueCache);
         case CSSPropertyWebkitAnimationFillMode: {
             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
             const AnimationList* t = style->animations();
@@ -1451,21 +1458,21 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
                 for (size_t i = 0; i < t->size(); ++i) {
                     switch (t->animation(i)->fillMode()) {
                     case AnimationFillModeNone:
-                        list->append(CSSPrimitiveValue::createIdentifier(CSSValueNone));
+                        list->append(primitiveValueCache->createIdentifierValue(CSSValueNone));
                         break;
                     case AnimationFillModeForwards:
-                        list->append(CSSPrimitiveValue::createIdentifier(CSSValueForwards));
+                        list->append(primitiveValueCache->createIdentifierValue(CSSValueForwards));
                         break;
                     case AnimationFillModeBackwards:
-                        list->append(CSSPrimitiveValue::createIdentifier(CSSValueBackwards));
+                        list->append(primitiveValueCache->createIdentifierValue(CSSValueBackwards));
                         break;
                     case AnimationFillModeBoth:
-                        list->append(CSSPrimitiveValue::createIdentifier(CSSValueBoth));
+                        list->append(primitiveValueCache->createIdentifierValue(CSSValueBoth));
                         break;
                     }
                 }
             } else
-                list->append(CSSPrimitiveValue::createIdentifier(CSSValueNone));
+                list->append(primitiveValueCache->createIdentifierValue(CSSValueNone));
             return list.release();
         }
         case CSSPropertyWebkitAnimationIterationCount: {
@@ -1475,12 +1482,12 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
                 for (size_t i = 0; i < t->size(); ++i) {
                     int iterationCount = t->animation(i)->iterationCount();
                     if (iterationCount == Animation::IterationCountInfinite)
-                        list->append(CSSPrimitiveValue::createIdentifier(CSSValueInfinite));
+                        list->append(primitiveValueCache->createIdentifierValue(CSSValueInfinite));
                     else
-                        list->append(CSSPrimitiveValue::create(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
+                        list->append(primitiveValueCache->createValue(iterationCount, CSSPrimitiveValue::CSS_NUMBER));
                 }
             } else
-                list->append(CSSPrimitiveValue::create(Animation::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
+                list->append(primitiveValueCache->createValue(Animation::initialAnimationIterationCount(), CSSPrimitiveValue::CSS_NUMBER));
             return list.release();
         }
         case CSSPropertyWebkitAnimationName: {
@@ -1488,9 +1495,9 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
             const AnimationList* t = style->animations();
             if (t) {
                 for (size_t i = 0; i < t->size(); ++i)
-                    list->append(CSSPrimitiveValue::create(t->animation(i)->name(), CSSPrimitiveValue::CSS_STRING));
+                    list->append(primitiveValueCache->createValue(t->animation(i)->name(), CSSPrimitiveValue::CSS_STRING));
             } else
-                list->append(CSSPrimitiveValue::createIdentifier(CSSValueNone));
+                list->append(primitiveValueCache->createIdentifierValue(CSSValueNone));
             return list.release();
         }
         case CSSPropertyWebkitAnimationPlayState: {
@@ -1500,103 +1507,103 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
                 for (size_t i = 0; i < t->size(); ++i) {
                     int prop = t->animation(i)->playState();
                     if (prop == AnimPlayStatePlaying)
-                        list->append(CSSPrimitiveValue::createIdentifier(CSSValueRunning));
+                        list->append(primitiveValueCache->createIdentifierValue(CSSValueRunning));
                     else
-                        list->append(CSSPrimitiveValue::createIdentifier(CSSValuePaused));
+                        list->append(primitiveValueCache->createIdentifierValue(CSSValuePaused));
                 }
             } else
-                list->append(CSSPrimitiveValue::createIdentifier(CSSValueRunning));
+                list->append(primitiveValueCache->createIdentifierValue(CSSValueRunning));
             return list.release();
         }
         case CSSPropertyWebkitAnimationTimingFunction:
             return getTimingFunctionValue(style->animations());
         case CSSPropertyWebkitAppearance:
-            return CSSPrimitiveValue::create(style->appearance());
+            return primitiveValueCache->createValue(style->appearance());
         case CSSPropertyWebkitBackfaceVisibility:
-            return CSSPrimitiveValue::createIdentifier((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
+            return primitiveValueCache->createIdentifierValue((style->backfaceVisibility() == BackfaceVisibilityHidden) ? CSSValueHidden : CSSValueVisible);
         case CSSPropertyWebkitBorderImage:
-            return valueForNinePieceImage(style->borderImage());
+            return valueForNinePieceImage(style->borderImage(), primitiveValueCache);
         case CSSPropertyWebkitMaskBoxImage:
-            return valueForNinePieceImage(style->maskBoxImage());
+            return valueForNinePieceImage(style->maskBoxImage(), primitiveValueCache);
         case CSSPropertyWebkitFontSizeDelta:
             // Not a real style property -- used by the editing engine -- so has no computed value.
             break;
         case CSSPropertyWebkitMarginBottomCollapse:
         case CSSPropertyWebkitMarginAfterCollapse:
-            return CSSPrimitiveValue::create(style->marginAfterCollapse());
+            return primitiveValueCache->createValue(style->marginAfterCollapse());
         case CSSPropertyWebkitMarginTopCollapse:
         case CSSPropertyWebkitMarginBeforeCollapse:
-            return CSSPrimitiveValue::create(style->marginBeforeCollapse());
+            return primitiveValueCache->createValue(style->marginBeforeCollapse());
         case CSSPropertyWebkitPerspective:
             if (!style->hasPerspective())
-                return CSSPrimitiveValue::createIdentifier(CSSValueNone);
-            return CSSPrimitiveValue::create(style->perspective(), CSSPrimitiveValue::CSS_NUMBER);
+                return primitiveValueCache->createIdentifierValue(CSSValueNone);
+            return primitiveValueCache->createValue(style->perspective(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyWebkitPerspectiveOrigin: {
             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
             if (renderer) {
                 IntRect box = sizingBox(renderer);
-                list->append(zoomAdjustedPixelValue(style->perspectiveOriginX().calcMinValue(box.width()), style.get()));
-                list->append(zoomAdjustedPixelValue(style->perspectiveOriginY().calcMinValue(box.height()), style.get()));
+                list->append(zoomAdjustedPixelValue(style->perspectiveOriginX().calcMinValue(box.width()), style.get(), primitiveValueCache));
+                list->append(zoomAdjustedPixelValue(style->perspectiveOriginY().calcMinValue(box.height()), style.get(), primitiveValueCache));
             }
             else {
-                list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), style.get()));
-                list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), style.get()));
+                list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginX(), style.get(), primitiveValueCache));
+                list->append(zoomAdjustedPixelValueForLength(style->perspectiveOriginY(), style.get(), primitiveValueCache));
                 
             }
             return list.release();
         }
         case CSSPropertyWebkitRtlOrdering:
             if (style->visuallyOrdered())
-                return CSSPrimitiveValue::createIdentifier(CSSValueVisual);
-            return CSSPrimitiveValue::createIdentifier(CSSValueLogical);
+                return primitiveValueCache->createIdentifierValue(CSSValueVisual);
+            return primitiveValueCache->createIdentifierValue(CSSValueLogical);
         case CSSPropertyWebkitUserDrag:
-            return CSSPrimitiveValue::create(style->userDrag());
+            return primitiveValueCache->createValue(style->userDrag());
         case CSSPropertyWebkitUserSelect:
-            return CSSPrimitiveValue::create(style->userSelect());
+            return primitiveValueCache->createValue(style->userSelect());
         case CSSPropertyBorderBottomLeftRadius:
-            return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), style.get());
+            return getBorderRadiusCornerValue(style->borderBottomLeftRadius(), style.get(), primitiveValueCache);
         case CSSPropertyBorderBottomRightRadius:
-            return getBorderRadiusCornerValue(style->borderBottomRightRadius(), style.get());
+            return getBorderRadiusCornerValue(style->borderBottomRightRadius(), style.get(), primitiveValueCache);
         case CSSPropertyBorderTopLeftRadius:
-            return getBorderRadiusCornerValue(style->borderTopLeftRadius(), style.get());
+            return getBorderRadiusCornerValue(style->borderTopLeftRadius(), style.get(), primitiveValueCache);
         case CSSPropertyBorderTopRightRadius:
-            return getBorderRadiusCornerValue(style->borderTopRightRadius(), style.get());
+            return getBorderRadiusCornerValue(style->borderTopRightRadius(), style.get(), primitiveValueCache);
         case CSSPropertyClip: {
             if (!style->hasClip())
-                return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
+                return primitiveValueCache->createIdentifierValue(CSSValueAuto);
             RefPtr<Rect> rect = Rect::create();
-            rect->setTop(zoomAdjustedPixelValue(style->clip().top().value(), style.get()));
-            rect->setRight(zoomAdjustedPixelValue(style->clip().right().value(), style.get()));
-            rect->setBottom(zoomAdjustedPixelValue(style->clip().bottom().value(), style.get()));
-            rect->setLeft(zoomAdjustedPixelValue(style->clip().left().value(), style.get()));
-            return CSSPrimitiveValue::create(rect.release());
+            rect->setTop(zoomAdjustedPixelValue(style->clip().top().value(), style.get(), primitiveValueCache));
+            rect->setRight(zoomAdjustedPixelValue(style->clip().right().value(), style.get(), primitiveValueCache));
+            rect->setBottom(zoomAdjustedPixelValue(style->clip().bottom().value(), style.get(), primitiveValueCache));
+            rect->setLeft(zoomAdjustedPixelValue(style->clip().left().value(), style.get(), primitiveValueCache));
+            return primitiveValueCache->createValue(rect.release());
         }
         case CSSPropertySpeak:
-            return CSSPrimitiveValue::create(style->speak());
+            return primitiveValueCache->createValue(style->speak());
         case CSSPropertyWebkitTransform:
-            return computedTransform(renderer, style.get());
+            return computedTransform(renderer, style.get(), primitiveValueCache);
         case CSSPropertyWebkitTransformOrigin: {
             RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
             if (renderer) {
                 IntRect box = sizingBox(renderer);
-                list->append(zoomAdjustedPixelValue(style->transformOriginX().calcMinValue(box.width()), style.get()));
-                list->append(zoomAdjustedPixelValue(style->transformOriginY().calcMinValue(box.height()), style.get()));
+                list->append(zoomAdjustedPixelValue(style->transformOriginX().calcMinValue(box.width()), style.get(), primitiveValueCache));
+                list->append(zoomAdjustedPixelValue(style->transformOriginY().calcMinValue(box.height()), style.get(), primitiveValueCache));
                 if (style->transformOriginZ() != 0)
-                    list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get()));
+                    list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get(), primitiveValueCache));
             } else {
-                list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), style.get()));
-                list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), style.get()));
+                list->append(zoomAdjustedPixelValueForLength(style->transformOriginX(), style.get(), primitiveValueCache));
+                list->append(zoomAdjustedPixelValueForLength(style->transformOriginY(), style.get(), primitiveValueCache));
                 if (style->transformOriginZ() != 0)
-                    list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get()));
+                    list->append(zoomAdjustedPixelValue(style->transformOriginZ(), style.get(), primitiveValueCache));
             }
             return list.release();
         }
         case CSSPropertyWebkitTransformStyle:
-            return CSSPrimitiveValue::createIdentifier((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
+            return primitiveValueCache->createIdentifierValue((style->transformStyle3D() == TransformStyle3DPreserve3D) ? CSSValuePreserve3d : CSSValueFlat);
         case CSSPropertyWebkitTransitionDelay:
-            return getDelayValue(style->transitions());
+            return getDelayValue(style->transitions(), primitiveValueCache);
         case CSSPropertyWebkitTransitionDuration:
-            return getDurationValue(style->transitions());
+            return getDurationValue(style->transitions(), primitiveValueCache);
         case CSSPropertyWebkitTransitionProperty: {
             RefPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
             const AnimationList* t = style->transitions();
@@ -1605,34 +1612,34 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
                     int prop = t->animation(i)->property();
                     RefPtr<CSSValue> propertyValue;
                     if (prop == cAnimateNone)
-                        propertyValue = CSSPrimitiveValue::createIdentifier(CSSValueNone);
+                        propertyValue = primitiveValueCache->createIdentifierValue(CSSValueNone);
                     else if (prop == cAnimateAll)
-                        propertyValue = CSSPrimitiveValue::createIdentifier(CSSValueAll);
+                        propertyValue = primitiveValueCache->createIdentifierValue(CSSValueAll);
                     else
-                        propertyValue = CSSPrimitiveValue::create(getPropertyName(static_cast<CSSPropertyID>(prop)), CSSPrimitiveValue::CSS_STRING);
+                        propertyValue = primitiveValueCache->createValue(getPropertyName(static_cast<CSSPropertyID>(prop)), CSSPrimitiveValue::CSS_STRING);
                     list->append(propertyValue);
                 }
             } else
-                list->append(CSSPrimitiveValue::createIdentifier(CSSValueAll));
+                list->append(primitiveValueCache->createIdentifierValue(CSSValueAll));
             return list.release();
         }
         case CSSPropertyWebkitTransitionTimingFunction:
             return getTimingFunctionValue(style->transitions());
         case CSSPropertyPointerEvents:
-            return CSSPrimitiveValue::create(style->pointerEvents());
+            return primitiveValueCache->createValue(style->pointerEvents());
         case CSSPropertyWebkitColorCorrection:
-            return CSSPrimitiveValue::create(style->colorSpace());
+            return primitiveValueCache->createValue(style->colorSpace());
         case CSSPropertyWebkitWritingMode:
-            return CSSPrimitiveValue::create(style->writingMode());
+            return primitiveValueCache->createValue(style->writingMode());
         case CSSPropertyWebkitTextCombine:
-            return CSSPrimitiveValue::create(style->textCombine());
+            return primitiveValueCache->createValue(style->textCombine());
 
         case CSSPropertyContent:
-            return contentToCSSValue(style.get());
+            return contentToCSSValue(style.get(), primitiveValueCache);
         case CSSPropertyCounterIncrement:
-            return counterToCSSValue(style.get(), propertyID);
+            return counterToCSSValue(style.get(), propertyID, primitiveValueCache);
         case CSSPropertyCounterReset:
-            return counterToCSSValue(style.get(), propertyID);
+            return counterToCSSValue(style.get(), propertyID, primitiveValueCache);
         
         /* Shorthand properties, currently not supported see bug 13658*/
         case CSSPropertyBackground:
index 6f0bf79..da520a1 100644 (file)
@@ -40,6 +40,7 @@
 #include "CSSMutableStyleDeclaration.h"
 #include "CSSPageRule.h"
 #include "CSSPrimitiveValue.h"
+#include "CSSPrimitiveValueCache.h"
 #include "CSSProperty.h"
 #include "CSSPropertyNames.h"
 #include "CSSPropertySourceData.h"
@@ -221,7 +222,7 @@ void CSSParser::setupParser(const char* prefix, const String& string, const char
 
 void CSSParser::parseSheet(CSSStyleSheet* sheet, const String& string, int startLineNumber, StyleRuleRangeMap* ruleRangeMap)
 {
-    m_styleSheet = sheet;
+    setStyleSheet(sheet);
     m_defaultNamespace = starAtom; // Reset the default namespace.
     m_ruleRangeMap = ruleRangeMap;
     if (ruleRangeMap) {
@@ -239,7 +240,7 @@ void CSSParser::parseSheet(CSSStyleSheet* sheet, const String& string, int start
 
 PassRefPtr<CSSRule> CSSParser::parseRule(CSSStyleSheet* sheet, const String& string)
 {
-    m_styleSheet = sheet;
+    setStyleSheet(sheet);
     m_allowNamespaceDeclarations = false;
     setupParser("@-webkit-rule{", string, "} ");
     cssyyparse(this);
@@ -248,7 +249,7 @@ PassRefPtr<CSSRule> CSSParser::parseRule(CSSStyleSheet* sheet, const String& str
 
 PassRefPtr<CSSRule> CSSParser::parseKeyframeRule(CSSStyleSheet *sheet, const String &string)
 {
-    m_styleSheet = sheet;
+    setStyleSheet(sheet);
     setupParser("@-webkit-keyframe-rule{ ", string, "} ");
     cssyyparse(this);
     return m_keyframe.release();
@@ -257,7 +258,7 @@ PassRefPtr<CSSRule> CSSParser::parseKeyframeRule(CSSStyleSheet *sheet, const Str
 bool CSSParser::parseValue(CSSMutableStyleDeclaration* declaration, int id, const String& string, bool important)
 {
     ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet());
-    m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet());
+    setStyleSheet(static_cast<CSSStyleSheet*>(declaration->stylesheet()));
 
     setupParser("@-webkit-value{", string, "} ");
 
@@ -310,7 +311,7 @@ bool CSSParser::parseColor(RGBA32& color, const String& string, bool strict)
 bool CSSParser::parseColor(CSSMutableStyleDeclaration* declaration, const String& string)
 {
     ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet());
-    m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet());
+    setStyleSheet(static_cast<CSSStyleSheet*>(declaration->stylesheet()));
 
     setupParser("@-webkit-decls{color:", string, "} ");
     cssyyparse(this);
@@ -339,7 +340,7 @@ void CSSParser::parseSelector(const String& string, Document* doc, CSSSelectorLi
 {
     RefPtr<CSSStyleSheet> dummyStyleSheet = CSSStyleSheet::create(doc);
 
-    m_styleSheet = dummyStyleSheet.get();
+    setStyleSheet(dummyStyleSheet.get());
     m_selectorListForParseSelector = &selectorList;
 
     setupParser("@-webkit-selector{", string, "}");
@@ -358,7 +359,7 @@ bool CSSParser::parseDeclaration(CSSMutableStyleDeclaration* declaration, const
     static const unsigned prefixLength = 15;
 
     ASSERT(!declaration->stylesheet() || declaration->stylesheet()->isCSSStyleSheet());
-    m_styleSheet = static_cast<CSSStyleSheet*>(declaration->stylesheet());
+    setStyleSheet(static_cast<CSSStyleSheet*>(declaration->stylesheet()));
     if (styleSourceData) {
         m_currentRuleData = CSSRuleSourceData::create();
         m_currentRuleData->styleSourceData = CSSStyleSourceData::create();
@@ -447,6 +448,12 @@ void CSSParser::clearProperties()
     m_numParsedPropertiesBeforeMarginBox = INVALID_NUM_PARSED_PROPERTIES;
     m_hasFontFaceOnlyValues = false;
 }
+    
+void CSSParser::setStyleSheet(CSSStyleSheet* styleSheet)
+{
+    m_styleSheet = styleSheet;
+    m_primitiveValueCache = document() ? document()->cssPrimitiveValueCache() : CSSPrimitiveValueCache::create();
+}
 
 Document* CSSParser::document() const
 {
@@ -906,9 +913,9 @@ bool CSSParser::parseValue(int propId, bool important)
                 if (list->length() != 1)
                     return false;
             } else if (!m_strict && value->id == CSSValueHand) // MSIE 5 compatibility :/
-                list->append(CSSPrimitiveValue::createIdentifier(CSSValuePointer));
+                list->append(primitiveValueCache()->createIdentifierValue(CSSValuePointer));
             else if (value && ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone))
-                list->append(CSSPrimitiveValue::createIdentifier(value->id));
+                list->append(primitiveValueCache()->createIdentifierValue(value->id));
             m_valueList->next();
             parsedValue = list.release();
             break;
@@ -1165,7 +1172,7 @@ bool CSSParser::parseValue(int propId, bool important)
                 case CSSValueUnderline:
                 case CSSValueOverline:
                 case CSSValueLineThrough:
-                    list->append(CSSPrimitiveValue::createIdentifier(value->id));
+                    list->append(primitiveValueCache()->createIdentifierValue(value->id));
                     break;
                 default:
                     isValid = false;
@@ -1224,19 +1231,19 @@ bool CSSParser::parseValue(int propId, bool important)
         validPrimitive = validUnit(value, FLength | FPercent, m_strict);
         if (!validPrimitive)
             return false;
-        RefPtr<CSSPrimitiveValue> parsedValue1 = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+        RefPtr<CSSPrimitiveValue> parsedValue1 = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
         RefPtr<CSSPrimitiveValue> parsedValue2;
         if (num == 2) {
             value = m_valueList->next();
             validPrimitive = validUnit(value, FLength | FPercent, m_strict);
             if (!validPrimitive)
                 return false;
-            parsedValue2 = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+            parsedValue2 = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
         } else
             parsedValue2 = parsedValue1;
 
         RefPtr<Pair> pair = Pair::create(parsedValue1.release(), parsedValue2.release());
-        RefPtr<CSSPrimitiveValue> val = CSSPrimitiveValue::create(pair.release());
+        RefPtr<CSSPrimitiveValue> val = primitiveValueCache()->createValue(pair.release());
         addProperty(propId, val.release(), important);
         return true;
     }
@@ -1415,7 +1422,7 @@ bool CSSParser::parseValue(int propId, bool important)
         else {
             // Accepting valueless numbers is a quirk of the -webkit prefixed version of the property.
             if (validUnit(value, FNumber | FLength | FNonNeg, m_strict)) {
-                RefPtr<CSSValue> val = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+                RefPtr<CSSValue> val = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
                 if (val) {
                     addProperty(propId, val.release(), important);
                     return true;
@@ -1833,13 +1840,13 @@ bool CSSParser::parseValue(int propId, bool important)
 
     if (validPrimitive) {
         if (id != 0)
-            parsedValue = CSSPrimitiveValue::createIdentifier(id);
+            parsedValue = primitiveValueCache()->createIdentifierValue(id);
         else if (value->unit == CSSPrimitiveValue::CSS_STRING)
-            parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
+            parsedValue = primitiveValueCache()->createValue(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
         else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
-            parsedValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
+            parsedValue = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
         else if (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_REMS)
-            parsedValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
+            parsedValue = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
         else if (value->unit >= CSSParserValue::Q_EMS)
             parsedValue = CSSQuirkPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_EMS);
         m_valueList->next();
@@ -1863,7 +1870,7 @@ PassRefPtr<CSSValue> CSSParser::parseWCSSInputProperty()
         inputProperty = String(value->string);
 
     if (!inputProperty.isEmpty())
-       parsedValue = CSSPrimitiveValue::create(inputProperty, CSSPrimitiveValue::CSS_STRING);
+       parsedValue = primitiveValueCache()->createValue(inputProperty, CSSPrimitiveValue::CSS_STRING);
 
     while (m_valueList->next()) {
     // pass all other values, if any. If we don't do this,
@@ -1891,11 +1898,11 @@ void CSSParser::addFillValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval)
         lval = rval;
 }
 
-static bool parseBackgroundClip(CSSParserValue* parserValue, RefPtr<CSSValue>& cssValue)
+static bool parseBackgroundClip(CSSParserValue* parserValue, RefPtr<CSSValue>& cssValue, CSSPrimitiveValueCache* primitiveValueCache)
 {
     if (parserValue->id == CSSValueBorderBox || parserValue->id == CSSValuePaddingBox
         || parserValue->id == CSSValueContentBox || parserValue->id == CSSValueWebkitText) {
-        cssValue = CSSPrimitiveValue::createIdentifier(parserValue->id);
+        cssValue = primitiveValueCache->createIdentifierValue(parserValue->id);
         return true;
     }
     return false;
@@ -1963,7 +1970,7 @@ bool CSSParser::parseFillShorthand(int propId, const int* properties, int numPro
                         addFillValue(repeatYValue, val2.release());
                     if (properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) {
                         // Reparse the value as a clip, and see if we succeed.
-                        if (parseBackgroundClip(parserValue, val1))
+                        if (parseBackgroundClip(parserValue, val1, primitiveValueCache()))
                             addFillValue(clipValue, val1.release()); // The property parsed successfully.
                         else
                             addFillValue(clipValue, CSSInitialValue::createImplicit()); // Some value was used for origin that is not supported by clip. Just reset clip instead.
@@ -2280,10 +2287,10 @@ bool CSSParser::parsePage(int propId, bool important)
         return false;
 
     if (value->id == CSSValueAuto) {
-        addProperty(propId, CSSPrimitiveValue::createIdentifier(value->id), important);
+        addProperty(propId, primitiveValueCache()->createIdentifierValue(value->id), important);
         return true;
     } else if (value->id == 0 && value->unit == CSSPrimitiveValue::CSS_IDENT) {
-        addProperty(propId, CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_STRING), important);
+        addProperty(propId, primitiveValueCache()->createValue(value->string, CSSPrimitiveValue::CSS_STRING), important);
         return true;
     }
     return false;
@@ -2325,14 +2332,14 @@ CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList* parsedV
     switch (value->id) {
     case CSSValueAuto:
         if (prevParamType == None) {
-            parsedValues->append(CSSPrimitiveValue::createIdentifier(value->id));
+            parsedValues->append(primitiveValueCache()->createIdentifierValue(value->id));
             return Auto;
         }
         return None;
     case CSSValueLandscape:
     case CSSValuePortrait:
         if (prevParamType == None || prevParamType == PageSize) {
-            parsedValues->append(CSSPrimitiveValue::createIdentifier(value->id));
+            parsedValues->append(primitiveValueCache()->createIdentifierValue(value->id));
             return Orientation;
         }
         return None;
@@ -2347,13 +2354,13 @@ CSSParser::SizeParameterType CSSParser::parseSizeParameter(CSSValueList* parsedV
         if (prevParamType == None || prevParamType == Orientation) {
             // Normalize to Page Size then Orientation order by prepending.
             // This is not specified by the CSS3 Paged Media specification, but for simpler processing later (CSSStyleSelector::applyPageSizeProperty).
-            parsedValues->prepend(CSSPrimitiveValue::createIdentifier(value->id));
+            parsedValues->prepend(primitiveValueCache()->createIdentifierValue(value->id));
             return PageSize;
         }
         return None;
     case 0:
         if (validUnit(value, FLength | FNonNeg, m_strict) && (prevParamType == None || prevParamType == Length)) {
-            parsedValues->append(CSSPrimitiveValue::create(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)));
+            parsedValues->append(primitiveValueCache()->createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)));
             return Length;
         }
         return None;
@@ -2436,10 +2443,10 @@ bool CSSParser::parseContent(int propId, bool important)
             case CSSValueNoCloseQuote:
             case CSSValueNone:
             case CSSValueNormal:
-                parsedValue = CSSPrimitiveValue::createIdentifier(val->id);
+                parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
             }
         } else if (val->unit == CSSPrimitiveValue::CSS_STRING) {
-            parsedValue = CSSPrimitiveValue::create(val->string, CSSPrimitiveValue::CSS_STRING);
+            parsedValue = primitiveValueCache()->createValue(val->string, CSSPrimitiveValue::CSS_STRING);
         }
         if (!parsedValue)
             break;
@@ -2476,7 +2483,7 @@ PassRefPtr<CSSValue> CSSParser::parseAttr(CSSParserValueList* args)
     if (document() && document()->isHTMLDocument())
         attrName = attrName.lower();
 
-    return CSSPrimitiveValue::create(attrName, CSSPrimitiveValue::CSS_ATTR);
+    return primitiveValueCache()->createValue(attrName, CSSPrimitiveValue::CSS_ATTR);
 }
 
 PassRefPtr<CSSValue> CSSParser::parseBackgroundColor()
@@ -2484,7 +2491,7 @@ PassRefPtr<CSSValue> CSSParser::parseBackgroundColor()
     int id = m_valueList->current()->id;
     if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || id == CSSValueCurrentcolor ||
         (id >= CSSValueGrey && id < CSSValueWebkitText && !m_strict))
-       return CSSPrimitiveValue::createIdentifier(id);
+       return primitiveValueCache()->createIdentifierValue(id);
     return parseColor();
 }
 
@@ -2530,10 +2537,10 @@ PassRefPtr<CSSValue> CSSParser::parseFillPositionXY(CSSParserValueList* valueLis
         else if (id == CSSValueCenter)
             // Center is ambiguous, so we're not sure which position we've found yet, an x or a y.
             percent = 50;
-        return CSSPrimitiveValue::create(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
+        return primitiveValueCache()->createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
     }
     if (validUnit(valueList->current(), FPercent | FLength, m_strict))
-        return CSSPrimitiveValue::create(valueList->current()->fValue,
+        return primitiveValueCache()->createValue(valueList->current()->fValue,
                                          (CSSPrimitiveValue::UnitTypes)valueList->current()->unit);
 
     return 0;
@@ -2576,7 +2583,7 @@ void CSSParser::parseFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue
         // is simply 50%.  This is our default.
         // For keywords, the keyword was either an x-keyword (left/right), a y-keyword (top/bottom), or an ambiguous keyword (center).
         // For left/right/center, the default of 50% in the y is still correct.
-        value2 = CSSPrimitiveValue::create(50, CSSPrimitiveValue::CSS_PERCENTAGE);
+        value2 = primitiveValueCache()->createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE);
 
     if (value1IsY || value2IsX)
         value1.swap(value2);
@@ -2589,20 +2596,20 @@ void CSSParser::parseFillRepeat(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& valu
     int id = m_valueList->current()->id;
     if (id == CSSValueRepeatX) {
         m_implicitShorthand = true;
-        value1 = CSSPrimitiveValue::createIdentifier(CSSValueRepeat);
-        value2 = CSSPrimitiveValue::createIdentifier(CSSValueNoRepeat);
+        value1 = primitiveValueCache()->createIdentifierValue(CSSValueRepeat);
+        value2 = primitiveValueCache()->createIdentifierValue(CSSValueNoRepeat);
         m_valueList->next();
         return;
     }
     if (id == CSSValueRepeatY) {
         m_implicitShorthand = true;
-        value1 = CSSPrimitiveValue::createIdentifier(CSSValueNoRepeat);
-        value2 = CSSPrimitiveValue::createIdentifier(CSSValueRepeat);
+        value1 = primitiveValueCache()->createIdentifierValue(CSSValueNoRepeat);
+        value2 = primitiveValueCache()->createIdentifierValue(CSSValueRepeat);
         m_valueList->next();
         return;
     }
     if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace)
-        value1 = CSSPrimitiveValue::createIdentifier(id);
+        value1 = primitiveValueCache()->createIdentifierValue(id);
     else {
         value1 = 0;
         return;
@@ -2618,12 +2625,12 @@ void CSSParser::parseFillRepeat(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& valu
         id = m_valueList->current()->id;
 
     if (value && (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace)) {
-        value2 = CSSPrimitiveValue::createIdentifier(id);
+        value2 = primitiveValueCache()->createIdentifierValue(id);
         m_valueList->next();
     } else {
         // If only one value was specified, value2 is the same as value1.
         m_implicitShorthand = true;
-        value2 = CSSPrimitiveValue::createIdentifier(static_cast<CSSPrimitiveValue*>(value1.get())->getIdent());
+        value2 = primitiveValueCache()->createIdentifierValue(static_cast<CSSPrimitiveValue*>(value1.get())->getIdent());
     }
 }
 
@@ -2633,39 +2640,39 @@ PassRefPtr<CSSValue> CSSParser::parseFillSize(int propId, bool& allowComma)
     CSSParserValue* value = m_valueList->current();
 
     if (value->id == CSSValueContain || value->id == CSSValueCover)
-        return CSSPrimitiveValue::createIdentifier(value->id);
+        return primitiveValueCache()->createIdentifierValue(value->id);
 
     RefPtr<CSSPrimitiveValue> parsedValue1;
 
     if (value->id == CSSValueAuto)
-        parsedValue1 = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_UNKNOWN);
+        parsedValue1 = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_UNKNOWN);
     else {
         if (!validUnit(value, FLength | FPercent, m_strict))
             return 0;
-        parsedValue1 = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+        parsedValue1 = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
     }
 
     CSSPropertyID property = static_cast<CSSPropertyID>(propId);
     RefPtr<CSSPrimitiveValue> parsedValue2;
     if ((value = m_valueList->next())) {
         if (value->id == CSSValueAuto)
-            parsedValue2 = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_UNKNOWN);
+            parsedValue2 = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_UNKNOWN);
         else if (value->unit == CSSParserValue::Operator && value->iValue == ',')
             allowComma = false;
         else {
             if (!validUnit(value, FLength | FPercent, m_strict))
                 return 0;
-            parsedValue2 = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+            parsedValue2 = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
         }
     }
     if (!parsedValue2) {
         if (property == CSSPropertyWebkitBackgroundSize || property == CSSPropertyWebkitMaskSize)
             parsedValue2 = parsedValue1;
         else
-            parsedValue2 = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_UNKNOWN);
+            parsedValue2 = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_UNKNOWN);
     }
 
-    return CSSPrimitiveValue::create(Pair::create(parsedValue1.release(), parsedValue2.release()));
+    return primitiveValueCache()->createValue(Pair::create(parsedValue1.release(), parsedValue2.release()));
 }
 
 bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2,
@@ -2716,7 +2723,7 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2,
                 case CSSPropertyBackgroundAttachment:
                 case CSSPropertyWebkitMaskAttachment:
                     if (val->id == CSSValueScroll || val->id == CSSValueFixed || val->id == CSSValueLocal) {
-                        currValue = CSSPrimitiveValue::createIdentifier(val->id);
+                        currValue = primitiveValueCache()->createIdentifierValue(val->id);
                         m_valueList->next();
                     }
                     break;
@@ -2735,17 +2742,17 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2,
                         val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox ||
                         ((propId == CSSPropertyWebkitBackgroundClip || propId == CSSPropertyWebkitMaskClip) &&
                          (val->id == CSSValueText || val->id == CSSValueWebkitText))) {
-                        currValue = CSSPrimitiveValue::createIdentifier(val->id);
+                        currValue = primitiveValueCache()->createIdentifierValue(val->id);
                         m_valueList->next();
                     }
                     break;
                 case CSSPropertyBackgroundClip:
-                    if (parseBackgroundClip(val, currValue))
+                    if (parseBackgroundClip(val, currValue, primitiveValueCache()))
                         m_valueList->next();
                     break;
                 case CSSPropertyBackgroundOrigin:
                     if (val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox) {
-                        currValue = CSSPrimitiveValue::createIdentifier(val->id);
+                        currValue = primitiveValueCache()->createIdentifierValue(val->id);
                         m_valueList->next();
                     }
                     break;
@@ -2773,7 +2780,7 @@ bool CSSParser::parseFillProperty(int propId, int& propId1, int& propId2,
                 case CSSPropertyWebkitBackgroundComposite:
                 case CSSPropertyWebkitMaskComposite:
                     if ((val->id >= CSSValueClear && val->id <= CSSValuePlusLighter) || val->id == CSSValueHighlight) {
-                        currValue = CSSPrimitiveValue::createIdentifier(val->id);
+                        currValue = primitiveValueCache()->createIdentifierValue(val->id);
                         m_valueList->next();
                     }
                     break;
@@ -2840,7 +2847,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationDelay()
 {
     CSSParserValue* value = m_valueList->current();
     if (validUnit(value, FTime, m_strict))
-        return CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+        return primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
     return 0;
 }
 
@@ -2848,7 +2855,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationDirection()
 {
     CSSParserValue* value = m_valueList->current();
     if (value->id == CSSValueNormal || value->id == CSSValueAlternate)
-        return CSSPrimitiveValue::createIdentifier(value->id);
+        return primitiveValueCache()->createIdentifierValue(value->id);
     return 0;
 }
 
@@ -2856,7 +2863,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationDuration()
 {
     CSSParserValue* value = m_valueList->current();
     if (validUnit(value, FTime | FNonNeg, m_strict))
-        return CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+        return primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
     return 0;
 }
 
@@ -2864,7 +2871,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationFillMode()
 {
     CSSParserValue* value = m_valueList->current();
     if (value->id == CSSValueNone || value->id == CSSValueForwards || value->id == CSSValueBackwards || value->id == CSSValueBoth)
-        return CSSPrimitiveValue::createIdentifier(value->id);
+        return primitiveValueCache()->createIdentifierValue(value->id);
     return 0;
 }
 
@@ -2872,9 +2879,9 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationIterationCount()
 {
     CSSParserValue* value = m_valueList->current();
     if (value->id == CSSValueInfinite)
-        return CSSPrimitiveValue::createIdentifier(value->id);
+        return primitiveValueCache()->createIdentifierValue(value->id);
     if (validUnit(value, FInteger | FNonNeg, m_strict))
-        return CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
+        return primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes)value->unit);
     return 0;
 }
 
@@ -2883,9 +2890,9 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationName()
     CSSParserValue* value = m_valueList->current();
     if (value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT) {
         if (value->id == CSSValueNone || (value->unit == CSSPrimitiveValue::CSS_STRING && equalIgnoringCase(value->string, "none"))) {
-            return CSSPrimitiveValue::createIdentifier(CSSValueNone);
+            return primitiveValueCache()->createIdentifierValue(CSSValueNone);
         } else {
-            return CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_STRING);
+            return primitiveValueCache()->createValue(value->string, CSSPrimitiveValue::CSS_STRING);
         }
     }
     return 0;
@@ -2895,7 +2902,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationPlayState()
 {
     CSSParserValue* value = m_valueList->current();
     if (value->id == CSSValueRunning || value->id == CSSValuePaused)
-        return CSSPrimitiveValue::createIdentifier(value->id);
+        return primitiveValueCache()->createIdentifierValue(value->id);
     return 0;
 }
 
@@ -2906,11 +2913,11 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationProperty()
         return 0;
     int result = cssPropertyID(value->string);
     if (result)
-        return CSSPrimitiveValue::createIdentifier(result);
+        return primitiveValueCache()->createIdentifierValue(result);
     if (equalIgnoringCase(value->string, "all"))
-        return CSSPrimitiveValue::createIdentifier(CSSValueAll);
+        return primitiveValueCache()->createIdentifierValue(CSSValueAll);
     if (equalIgnoringCase(value->string, "none"))
-        return CSSPrimitiveValue::createIdentifier(CSSValueNone);
+        return primitiveValueCache()->createIdentifierValue(CSSValueNone);
     return 0;
 }
 
@@ -2921,7 +2928,7 @@ bool CSSParser::parseTransformOriginShorthand(RefPtr<CSSValue>& value1, RefPtr<C
     // now get z
     if (m_valueList->current()) {
         if (validUnit(m_valueList->current(), FLength, m_strict)) {
-            value3 = CSSPrimitiveValue::create(m_valueList->current()->fValue,
+            value3 = primitiveValueCache()->createValue(m_valueList->current()->fValue,
                                              (CSSPrimitiveValue::UnitTypes)m_valueList->current()->unit);
             m_valueList->next();
             return true;
@@ -2954,7 +2961,7 @@ PassRefPtr<CSSValue> CSSParser::parseAnimationTimingFunction()
     CSSParserValue* value = m_valueList->current();
     if (value->id == CSSValueEase || value->id == CSSValueLinear || value->id == CSSValueEaseIn || value->id == CSSValueEaseOut
         || value->id == CSSValueEaseInOut || value->id == CSSValueStepStart || value->id == CSSValueStepEnd)
-        return CSSPrimitiveValue::createIdentifier(value->id);
+        return primitiveValueCache()->createIdentifierValue(value->id);
 
     // We must be a function.
     if (value->unit != CSSParserValue::Function)
@@ -3144,7 +3151,7 @@ bool CSSParser::parseDashboardRegions(int propId, bool important)
     if (value->id == CSSValueNone) {
         if (m_valueList->next())
             return false;
-        addProperty(propId, CSSPrimitiveValue::createIdentifier(value->id), important);
+        addProperty(propId, primitiveValueCache()->createIdentifierValue(value->id), important);
         return valid;
     }
 
@@ -3214,7 +3221,7 @@ bool CSSParser::parseDashboardRegions(int propId, bool important)
 
         if (numArgs == DASHBOARD_REGION_SHORT_NUM_PARAMETERS || numArgs == (DASHBOARD_REGION_SHORT_NUM_PARAMETERS*2-1)) {
             // This originally used CSSValueInvalid by accident. It might be more logical to use something else.
-            RefPtr<CSSPrimitiveValue> amount = CSSPrimitiveValue::createIdentifier(CSSValueInvalid);
+            RefPtr<CSSPrimitiveValue> amount = primitiveValueCache()->createIdentifierValue(CSSValueInvalid);
 
             region->setTop(amount);
             region->setRight(amount);
@@ -3232,8 +3239,8 @@ bool CSSParser::parseDashboardRegions(int propId, bool important)
                     break;
 
                 RefPtr<CSSPrimitiveValue> amount = arg->id == CSSValueAuto ?
-                    CSSPrimitiveValue::createIdentifier(CSSValueAuto) :
-                    CSSPrimitiveValue::create(arg->fValue, (CSSPrimitiveValue::UnitTypes) arg->unit);
+                    primitiveValueCache()->createIdentifierValue(CSSValueAuto) :
+                    primitiveValueCache()->createValue(arg->fValue, (CSSPrimitiveValue::UnitTypes) arg->unit);
 
                 if (i == 0)
                     region->setTop(amount);
@@ -3253,7 +3260,7 @@ bool CSSParser::parseDashboardRegions(int propId, bool important)
     }
 
     if (valid)
-        addProperty(propId, CSSPrimitiveValue::create(firstRegion.release()), important);
+        addProperty(propId, primitiveValueCache()->createValue(firstRegion.release()), important);
 
     return valid;
 }
@@ -3271,11 +3278,11 @@ PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bo
     CSSParserValue* i = args->current();
     if (i->unit != CSSPrimitiveValue::CSS_IDENT)
         return 0;
-    RefPtr<CSSPrimitiveValue> identifier = CSSPrimitiveValue::create(i->string, CSSPrimitiveValue::CSS_STRING);
+    RefPtr<CSSPrimitiveValue> identifier = primitiveValueCache()->createValue(i->string, CSSPrimitiveValue::CSS_STRING);
 
     RefPtr<CSSPrimitiveValue> separator;
     if (!counters)
-        separator = CSSPrimitiveValue::create(String(), CSSPrimitiveValue::CSS_STRING);
+        separator = primitiveValueCache()->createValue(String(), CSSPrimitiveValue::CSS_STRING);
     else {
         i = args->next();
         if (i->unit != CSSParserValue::Operator || i->iValue != ',')
@@ -3285,13 +3292,13 @@ PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bo
         if (i->unit != CSSPrimitiveValue::CSS_STRING)
             return 0;
 
-        separator = CSSPrimitiveValue::create(i->string, (CSSPrimitiveValue::UnitTypes) i->unit);
+        separator = primitiveValueCache()->createValue(i->string, (CSSPrimitiveValue::UnitTypes) i->unit);
     }
 
     RefPtr<CSSPrimitiveValue> listStyle;
     i = args->next();
     if (!i) // Make the list style default decimal
-        listStyle = CSSPrimitiveValue::create(CSSValueDecimal - CSSValueDisc, CSSPrimitiveValue::CSS_NUMBER);
+        listStyle = primitiveValueCache()->createValue(CSSValueDecimal - CSSValueDisc, CSSPrimitiveValue::CSS_NUMBER);
     else {
         if (i->unit != CSSParserValue::Operator || i->iValue != ',')
             return 0;
@@ -3308,10 +3315,10 @@ PassRefPtr<CSSValue> CSSParser::parseCounterContent(CSSParserValueList* args, bo
         else
             return 0;
 
-        listStyle = CSSPrimitiveValue::create(ls, (CSSPrimitiveValue::UnitTypes) i->unit);
+        listStyle = primitiveValueCache()->createValue(ls, (CSSPrimitiveValue::UnitTypes) i->unit);
     }
 
-    return CSSPrimitiveValue::create(Counter::create(identifier.release(), listStyle.release(), separator.release()));
+    return primitiveValueCache()->createValue(Counter::create(identifier.release(), listStyle.release(), separator.release()));
 }
 
 bool CSSParser::parseShape(int propId, bool important)
@@ -3334,8 +3341,8 @@ bool CSSParser::parseShape(int propId, bool important)
         if (!valid)
             break;
         RefPtr<CSSPrimitiveValue> length = a->id == CSSValueAuto ?
-            CSSPrimitiveValue::createIdentifier(CSSValueAuto) :
-            CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
+            primitiveValueCache()->createIdentifierValue(CSSValueAuto) :
+            primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
         if (i == 0)
             rect->setTop(length);
         else if (i == 1)
@@ -3356,7 +3363,7 @@ bool CSSParser::parseShape(int propId, bool important)
         i++;
     }
     if (valid) {
-        addProperty(propId, CSSPrimitiveValue::create(rect.release()), important);
+        addProperty(propId, primitiveValueCache()->createValue(rect.release()), important);
         m_valueList->next();
         return true;
     }
@@ -3378,15 +3385,15 @@ bool CSSParser::parseFont(bool important)
             } else if (id == CSSValueItalic || id == CSSValueOblique) {
                 if (font->style)
                     return false;
-                font->style = CSSPrimitiveValue::createIdentifier(id);
+                font->style = primitiveValueCache()->createIdentifierValue(id);
             } else if (id == CSSValueSmallCaps) {
                 if (font->variant)
                     return false;
-                font->variant = CSSPrimitiveValue::createIdentifier(id);
+                font->variant = primitiveValueCache()->createIdentifierValue(id);
             } else if (id >= CSSValueBold && id <= CSSValueLighter) {
                 if (font->weight)
                     return false;
-                font->weight = CSSPrimitiveValue::createIdentifier(id);
+                font->weight = primitiveValueCache()->createIdentifierValue(id);
             } else {
                 valid = false;
             }
@@ -3413,7 +3420,7 @@ bool CSSParser::parseFont(bool important)
                 val = CSSValue900;
 
             if (val)
-                font->weight = CSSPrimitiveValue::createIdentifier(val);
+                font->weight = primitiveValueCache()->createIdentifierValue(val);
             else
                 valid = false;
         } else {
@@ -3428,18 +3435,18 @@ bool CSSParser::parseFont(bool important)
 
     // set undefined values to default
     if (!font->style)
-        font->style = CSSPrimitiveValue::createIdentifier(CSSValueNormal);
+        font->style = primitiveValueCache()->createIdentifierValue(CSSValueNormal);
     if (!font->variant)
-        font->variant = CSSPrimitiveValue::createIdentifier(CSSValueNormal);
+        font->variant = primitiveValueCache()->createIdentifierValue(CSSValueNormal);
     if (!font->weight)
-        font->weight = CSSPrimitiveValue::createIdentifier(CSSValueNormal);
+        font->weight = primitiveValueCache()->createIdentifierValue(CSSValueNormal);
 
     // now a font size _must_ come
     // <absolute-size> | <relative-size> | <length> | <percentage> | inherit
     if (value->id >= CSSValueXxSmall && value->id <= CSSValueLarger)
-        font->size = CSSPrimitiveValue::createIdentifier(value->id);
+        font->size = primitiveValueCache()->createIdentifierValue(value->id);
     else if (validUnit(value, FLength | FPercent | FNonNeg, m_strict))
-        font->size = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
+        font->size = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
     value = m_valueList->next();
     if (!font->size || !value)
         return false;
@@ -3452,7 +3459,7 @@ bool CSSParser::parseFont(bool important)
         if (value->id == CSSValueNormal) {
             // default value, nothing to do
         } else if (validUnit(value, FNumber | FLength | FPercent | FNonNeg, m_strict))
-            font->lineHeight = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
+            font->lineHeight = primitiveValueCache()->createValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
         else
             return false;
         value = m_valueList->next();
@@ -3461,7 +3468,7 @@ bool CSSParser::parseFont(bool important)
     }
 
     if (!font->lineHeight)
-        font->lineHeight = CSSPrimitiveValue::createIdentifier(CSSValueNormal);
+        font->lineHeight = primitiveValueCache()->createIdentifierValue(CSSValueNormal);
 
     // font family must come now
     font->family = parseFontFamily();
@@ -3491,7 +3498,7 @@ PassRefPtr<CSSValueList> CSSParser::parseFontFamily()
             if (currFamily)
                 currFamily->appendSpaceSeparated(value->string.characters, value->string.length);
             else if (nextValBreaksFont || !nextValIsFontName)
-                list->append(CSSPrimitiveValue::createIdentifier(value->id));
+                list->append(primitiveValueCache()->createIdentifierValue(value->id));
             else {
                 RefPtr<FontFamilyValue> newFamily = FontFamilyValue::create(value->string);
                 currFamily = newFamily.get();
@@ -3544,12 +3551,12 @@ bool CSSParser::parseFontStyle(bool important)
         if (!expectComma) {
             expectComma = true;
             if (val->id == CSSValueNormal || val->id == CSSValueItalic || val->id == CSSValueOblique)
-                parsedValue = CSSPrimitiveValue::createIdentifier(val->id);
+                parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
             else if (val->id == CSSValueAll && !values) {
                 // 'all' is only allowed in @font-face and with no other values. Make a value list to
                 // indicate that we are in the @font-face case.
                 values = CSSValueList::createCommaSeparated();
-                parsedValue = CSSPrimitiveValue::createIdentifier(val->id);
+                parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
             }
         } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
             expectComma = false;
@@ -3591,12 +3598,12 @@ bool CSSParser::parseFontVariant(bool important)
         if (!expectComma) {
             expectComma = true;
             if (val->id == CSSValueNormal || val->id == CSSValueSmallCaps)
-                parsedValue = CSSPrimitiveValue::createIdentifier(val->id);
+                parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
             else if (val->id == CSSValueAll && !values) {
                 // 'all' is only allowed in @font-face and with no other values. Make a value list to
                 // indicate that we are in the @font-face case.
                 values = CSSValueList::createCommaSeparated();
-                parsedValue = CSSPrimitiveValue::createIdentifier(val->id);
+                parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
             }
         } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
             expectComma = false;
@@ -3639,17 +3646,17 @@ bool CSSParser::parseFontWeight(bool important)
             expectComma = true;
             if (val->unit == CSSPrimitiveValue::CSS_IDENT) {
                 if (val->id >= CSSValueNormal && val->id <= CSSValue900)
-                    parsedValue = CSSPrimitiveValue::createIdentifier(val->id);
+                    parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
                 else if (val->id == CSSValueAll && !values) {
                     // 'all' is only allowed in @font-face and with no other values. Make a value list to
                     // indicate that we are in the @font-face case.
                     values = CSSValueList::createCommaSeparated();
-                    parsedValue = CSSPrimitiveValue::createIdentifier(val->id);
+                    parsedValue = primitiveValueCache()->createIdentifierValue(val->id);
                 }
             } else if (validUnit(val, FInteger | FNonNeg, false)) {
                 int weight = static_cast<int>(val->fValue);
                 if (!(weight % 100) && weight >= 100 && weight <= 900)
-                    parsedValue = CSSPrimitiveValue::createIdentifier(CSSValue100 + weight / 100 - 1);
+                    parsedValue = primitiveValueCache()->createIdentifierValue(CSSValue100 + weight / 100 - 1);
             }
         } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
             expectComma = false;
@@ -4140,7 +4147,7 @@ PassRefPtr<CSSPrimitiveValue> CSSParser::parseColor(CSSParserValue* value)
     RGBA32 c = Color::transparent;
     if (!parseColorFromValue(value ? value : m_valueList->current(), c))
         return 0;
-    return CSSPrimitiveValue::createColor(c);
+    return primitiveValueCache()->createColorValue(c);
 }
 
 bool CSSParser::parseColorFromValue(CSSParserValue* value, RGBA32& c)
@@ -4198,8 +4205,9 @@ bool CSSParser::parseColorFromValue(CSSParserValue* value, RGBA32& c)
 // This class tracks parsing state for shadow values.  If it goes out of scope (e.g., due to an early return)
 // without the allowBreak bit being set, then it will clean up all of the objects and destroy them.
 struct ShadowParseContext {
-    ShadowParseContext(CSSPropertyID prop)
+    ShadowParseContext(CSSPropertyID prop, CSSPrimitiveValueCache* primitiveValueCache)
         : property(prop)
+        , m_primitiveValueCache(primitiveValueCache)
         , allowX(true)
         , allowY(false)
         , allowBlur(false)
@@ -4242,7 +4250,7 @@ struct ShadowParseContext {
 
     void commitLength(CSSParserValue* v)
     {
-        RefPtr<CSSPrimitiveValue> val = CSSPrimitiveValue::create(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit);
+        RefPtr<CSSPrimitiveValue> val = m_primitiveValueCache->createValue(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit);
 
         if (allowX) {
             x = val.release();
@@ -4284,7 +4292,7 @@ struct ShadowParseContext {
 
     void commitStyle(CSSParserValue* v)
     {
-        style = CSSPrimitiveValue::createIdentifier(v->id);
+        style = m_primitiveValueCache->createIdentifierValue(v->id);
         allowStyle = false;
         if (allowX)
             allowBreak = false;
@@ -4296,6 +4304,7 @@ struct ShadowParseContext {
     }
 
     CSSPropertyID property;
+    CSSPrimitiveValueCache* m_primitiveValueCache;
 
     RefPtr<CSSValueList> values;
     RefPtr<CSSPrimitiveValue> x;
@@ -4316,7 +4325,7 @@ struct ShadowParseContext {
 
 bool CSSParser::parseShadow(int propId, bool important)
 {
-    ShadowParseContext context(static_cast<CSSPropertyID>(propId));
+    ShadowParseContext context(static_cast<CSSPropertyID>(propId), primitiveValueCache());
     CSSParserValue* val;
     while ((val = m_valueList->current())) {
         // Check for a comma break first.
@@ -4352,7 +4361,7 @@ bool CSSParser::parseShadow(int propId, bool important)
             if (isColor) {
                 if (!context.allowColor)
                     return false;
-                parsedColor = CSSPrimitiveValue::createIdentifier(val->id);
+                parsedColor = primitiveValueCache()->createIdentifierValue(val->id);
             }
 
             if (!parsedColor)
@@ -4409,11 +4418,11 @@ bool CSSParser::parseReflect(int propId, bool important)
     val = m_valueList->next();
     RefPtr<CSSPrimitiveValue> offset;
     if (!val)
-        offset = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_PX);
+        offset = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_PX);
     else {
         if (!validUnit(val, FLength | FPercent, m_strict))
             return false;
-        offset = CSSPrimitiveValue::create(val->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(val->unit));
+        offset = primitiveValueCache()->createValue(val->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(val->unit));
     }
 
     // Now for the mask.
@@ -4431,8 +4440,9 @@ bool CSSParser::parseReflect(int propId, bool important)
 }
 
 struct BorderImageParseContext {
-    BorderImageParseContext()
-    : m_allowBreak(false)
+    BorderImageParseContext(CSSPrimitiveValueCache* primitiveValueCache)
+    : m_primitiveValueCache(primitiveValueCache)
+    , m_allowBreak(false)
     , m_allowNumber(false)
     , m_allowSlash(false)
     , m_allowWidth(false)
@@ -4454,7 +4464,7 @@ struct BorderImageParseContext {
     void commitImage(PassRefPtr<CSSValue> image) { m_image = image; m_allowNumber = true; }
     void commitNumber(CSSParserValue* v)
     {
-        PassRefPtr<CSSPrimitiveValue> val = CSSPrimitiveValue::create(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit);
+        PassRefPtr<CSSPrimitiveValue> val = m_primitiveValueCache->createValue(v->fValue, (CSSPrimitiveValue::UnitTypes)v->unit);
         if (!m_top)
             m_top = val;
         else if (!m_right)
@@ -4498,16 +4508,16 @@ struct BorderImageParseContext {
     {
         // We need to clone and repeat values for any omissions.
         if (!m_right) {
-            m_right = CSSPrimitiveValue::create(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
-            m_bottom = CSSPrimitiveValue::create(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
-            m_left = CSSPrimitiveValue::create(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
+            m_right = m_primitiveValueCache->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
+            m_bottom = m_primitiveValueCache->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
+            m_left = m_primitiveValueCache->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
         }
         if (!m_bottom) {
-            m_bottom = CSSPrimitiveValue::create(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
-            m_left = CSSPrimitiveValue::create(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType());
+            m_bottom = m_primitiveValueCache->createValue(m_top->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_top->primitiveType());
+            m_left = m_primitiveValueCache->createValue(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType());
         }
         if (!m_left)
-             m_left = CSSPrimitiveValue::create(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType());
+             m_left = m_primitiveValueCache->createValue(m_right->getDoubleValue(), (CSSPrimitiveValue::UnitTypes)m_right->primitiveType());
 
         // Now build a rect value to hold all four of our primitive values.
         RefPtr<Rect> rect = Rect::create();
@@ -4544,6 +4554,8 @@ struct BorderImageParseContext {
         // Make our new border image value now.
         return CSSBorderImageValue::create(m_image, rect.release(), m_horizontalRule, m_verticalRule);
     }
+    
+    CSSPrimitiveValueCache* m_primitiveValueCache;
 
     bool m_allowBreak;
     bool m_allowNumber;
@@ -4570,7 +4582,7 @@ struct BorderImageParseContext {
 bool CSSParser::parseBorderImage(int propId, bool important, RefPtr<CSSValue>& result)
 {
     // Look for an image initially.  If the first value is not a URI, then we're done.
-    BorderImageParseContext context;
+    BorderImageParseContext context(primitiveValueCache());
     CSSParserValue* val = m_valueList->current();
     if (val->unit == CSSPrimitiveValue::CSS_URI && m_styleSheet) {
         // FIXME: The completeURL call should be done when using the CSSImageValue,
@@ -4604,7 +4616,7 @@ bool CSSParser::parseBorderImage(int propId, bool important, RefPtr<CSSValue>& r
 
     if (context.allowNumber() && propId != CSSPropertyWebkitBorderImage) {
         // Allow the slices to be omitted for images that don't fit to a border.  We just set the slices to be 0.
-        context.m_top = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_NUMBER);
+        context.m_top = primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_NUMBER);
         context.m_allowBreak = true;
     }
 
@@ -4659,7 +4671,7 @@ bool CSSParser::parseBorderRadius(int propId, bool important)
         if (!validUnit(value, FLength | FPercent, m_strict))
             return false;
 
-        RefPtr<CSSPrimitiveValue> radius = CSSPrimitiveValue::create(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit));
+        RefPtr<CSSPrimitiveValue> radius = primitiveValueCache()->createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit));
 
         if (!indexAfterSlash) {
             radii[0][i] = radius;
@@ -4681,10 +4693,10 @@ bool CSSParser::parseBorderRadius(int propId, bool important)
         completeBorderRadii(radii[1]);
 
     m_implicitShorthand = true;
-    addProperty(CSSPropertyBorderTopLeftRadius, CSSPrimitiveValue::create(Pair::create(radii[0][0].release(), radii[1][0].release())), important);
-    addProperty(CSSPropertyBorderTopRightRadius, CSSPrimitiveValue::create(Pair::create(radii[0][1].release(), radii[1][1].release())), important);
-    addProperty(CSSPropertyBorderBottomRightRadius, CSSPrimitiveValue::create(Pair::create(radii[0][2].release(), radii[1][2].release())), important);
-    addProperty(CSSPropertyBorderBottomLeftRadius, CSSPrimitiveValue::create(Pair::create(radii[0][3].release(), radii[1][3].release())), important);
+    addProperty(CSSPropertyBorderTopLeftRadius, primitiveValueCache()->createValue(Pair::create(radii[0][0].release(), radii[1][0].release())), important);
+    addProperty(CSSPropertyBorderTopRightRadius, primitiveValueCache()->createValue(Pair::create(radii[0][1].release(), radii[1][1].release())), important);
+    addProperty(CSSPropertyBorderBottomRightRadius, primitiveValueCache()->createValue(Pair::create(radii[0][2].release(), radii[1][2].release())), important);
+    addProperty(CSSPropertyBorderBottomLeftRadius, primitiveValueCache()->createValue(Pair::create(radii[0][3].release(), radii[1][3].release())), important);
     m_implicitShorthand = false;
     return true;
 }
@@ -4701,7 +4713,7 @@ bool CSSParser::parseCounter(int propId, int defaultValue, bool important)
         switch (state) {
             case ID:
                 if (val && val->unit == CSSPrimitiveValue::CSS_IDENT) {
-                    counterName = CSSPrimitiveValue::create(val->string, CSSPrimitiveValue::CSS_STRING);
+                    counterName = primitiveValueCache()->createValue(val->string, CSSPrimitiveValue::CSS_STRING);
                     state = VAL;
                     m_valueList->next();
                     continue;
@@ -4714,8 +4726,8 @@ bool CSSParser::parseCounter(int propId, int defaultValue, bool important)
                     m_valueList->next();
                 }
 
-                list->append(CSSPrimitiveValue::create(Pair::create(counterName.release(),
-                    CSSPrimitiveValue::create(i, CSSPrimitiveValue::CSS_NUMBER))));
+                list->append(primitiveValueCache()->createValue(Pair::create(counterName.release(),
+                    primitiveValueCache()->createValue(i, CSSPrimitiveValue::CSS_NUMBER))));
                 state = ID;
                 continue;
             }
@@ -4732,20 +4744,20 @@ bool CSSParser::parseCounter(int propId, int defaultValue, bool important)
 }
 
 // This should go away once we drop support for -webkit-gradient
-static PassRefPtr<CSSPrimitiveValue> parseDeprecatedGradientPoint(CSSParserValue* a, bool horizontal)
+static PassRefPtr<CSSPrimitiveValue> parseDeprecatedGradientPoint(CSSParserValue* a, bool horizontal, CSSPrimitiveValueCache* primitiveValueCache)
 {
     RefPtr<CSSPrimitiveValue> result;
     if (a->unit == CSSPrimitiveValue::CSS_IDENT) {
         if ((equalIgnoringCase(a->string, "left") && horizontal) || 
             (equalIgnoringCase(a->string, "top") && !horizontal))
-            result = CSSPrimitiveValue::create(0., CSSPrimitiveValue::CSS_PERCENTAGE);
+            result = primitiveValueCache->createValue(0., CSSPrimitiveValue::CSS_PERCENTAGE);
         else if ((equalIgnoringCase(a->string, "right") && horizontal) ||
                  (equalIgnoringCase(a->string, "bottom") && !horizontal))
-            result = CSSPrimitiveValue::create(100., CSSPrimitiveValue::CSS_PERCENTAGE);
+            result = primitiveValueCache->createValue(100., CSSPrimitiveValue::CSS_PERCENTAGE);
         else if (equalIgnoringCase(a->string, "center"))
-            result = CSSPrimitiveValue::create(50., CSSPrimitiveValue::CSS_PERCENTAGE);
+            result = primitiveValueCache->createValue(50., CSSPrimitiveValue::CSS_PERCENTAGE);
     } else if (a->unit == CSSPrimitiveValue::CSS_NUMBER || a->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
-        result = CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit);
+        result = primitiveValueCache->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit);
     return result;
 }
 
@@ -4770,13 +4782,13 @@ static bool parseDeprecatedGradientColorStop(CSSParser* p, CSSParserValue* a, CS
             return false;
 
         if (equalIgnoringCase(a->function->name, "from("))
-            stop.m_position = CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_NUMBER);
+            stop.m_position = p->primitiveValueCache()->createValue(0, CSSPrimitiveValue::CSS_NUMBER);
         else
-            stop.m_position = CSSPrimitiveValue::create(1, CSSPrimitiveValue::CSS_NUMBER);
+            stop.m_position = p->primitiveValueCache()->createValue(1, CSSPrimitiveValue::CSS_NUMBER);
 
         int id = args->current()->id;
         if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu)
-            stop.m_color = CSSPrimitiveValue::createIdentifier(id);
+            stop.m_color = p->primitiveValueCache()->createIdentifierValue(id);
         else
             stop.m_color = p->parseColor(args->current());
         if (!stop.m_color)
@@ -4790,9 +4802,9 @@ static bool parseDeprecatedGradientColorStop(CSSParser* p, CSSParserValue* a, CS
 
         CSSParserValue* stopArg = args->current();
         if (stopArg->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
-            stop.m_position = CSSPrimitiveValue::create(stopArg->fValue / 100, CSSPrimitiveValue::CSS_NUMBER);
+            stop.m_position = p->primitiveValueCache()->createValue(stopArg->fValue / 100, CSSPrimitiveValue::CSS_NUMBER);
         else if (stopArg->unit == CSSPrimitiveValue::CSS_NUMBER)
-            stop.m_position = CSSPrimitiveValue::create(stopArg->fValue, CSSPrimitiveValue::CSS_NUMBER);
+            stop.m_position = p->primitiveValueCache()->createValue(stopArg->fValue, CSSPrimitiveValue::CSS_NUMBER);
         else
             return false;
 
@@ -4803,7 +4815,7 @@ static bool parseDeprecatedGradientColorStop(CSSParser* p, CSSParserValue* a, CS
         stopArg = args->next();
         int id = stopArg->id;
         if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu)
-            stop.m_color = CSSPrimitiveValue::createIdentifier(id);
+            stop.m_color = p->primitiveValueCache()->createIdentifierValue(id);
         else
             stop.m_color = p->parseColor(stopArg);
         if (!stop.m_color)
@@ -4853,7 +4865,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient)
     a = args->next();
     if (!a)
         return false;
-    RefPtr<CSSPrimitiveValue> point = parseDeprecatedGradientPoint(a, true);
+    RefPtr<CSSPrimitiveValue> point = parseDeprecatedGradientPoint(a, true, primitiveValueCache());
     if (!point)
         return false;
     result->setFirstX(point.release());
@@ -4862,7 +4874,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient)
     a = args->next();
     if (!a)
         return false;
-    point = parseDeprecatedGradientPoint(a, false);
+    point = parseDeprecatedGradientPoint(a, false, primitiveValueCache());
     if (!point)
         return false;
     result->setFirstY(point.release());
@@ -4877,7 +4889,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient)
         a = args->next();
         if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER)
             return false;
-        static_cast<CSSRadialGradientValue*>(result.get())->setFirstRadius(CSSPrimitiveValue::create(a->fValue, CSSPrimitiveValue::CSS_NUMBER));
+        static_cast<CSSRadialGradientValue*>(result.get())->setFirstRadius(primitiveValueCache()->createValue(a->fValue, CSSPrimitiveValue::CSS_NUMBER));
 
         // Comma after the first radius.
         a = args->next();
@@ -4890,7 +4902,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient)
     a = args->next();
     if (!a)
         return false;
-    point = parseDeprecatedGradientPoint(a, true);
+    point = parseDeprecatedGradientPoint(a, true, primitiveValueCache());
     if (!point)
         return false;
     result->setSecondX(point.release());
@@ -4899,7 +4911,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient)
     a = args->next();
     if (!a)
         return false;
-    point = parseDeprecatedGradientPoint(a, false);
+    point = parseDeprecatedGradientPoint(a, false, primitiveValueCache());
     if (!point)
         return false;
     result->setSecondY(point.release());
@@ -4914,7 +4926,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient)
         a = args->next();
         if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER)
             return false;
-        static_cast<CSSRadialGradientValue*>(result.get())->setSecondRadius(CSSPrimitiveValue::create(a->fValue, CSSPrimitiveValue::CSS_NUMBER));
+        static_cast<CSSRadialGradientValue*>(result.get())->setSecondRadius(primitiveValueCache()->createValue(a->fValue, CSSPrimitiveValue::CSS_NUMBER));
     }
 
     // We now will accept any number of stops (0 or more).
@@ -4943,7 +4955,7 @@ bool CSSParser::parseDeprecatedGradient(RefPtr<CSSValue>& gradient)
     return true;
 }
 
-static PassRefPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, bool& isHorizontal)
+static PassRefPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, bool& isHorizontal, CSSPrimitiveValueCache* primitiveValueCache)
 {
     if (a->unit != CSSPrimitiveValue::CSS_IDENT)
         return 0;
@@ -4960,14 +4972,14 @@ static PassRefPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, boo
         default:
             return 0;
     }
-    return CSSPrimitiveValue::createIdentifier(a->id);
+    return primitiveValueCache->createIdentifierValue(a->id);
 }
 
 static PassRefPtr<CSSPrimitiveValue> parseGradientColorOrKeyword(CSSParser* p, CSSParserValue* value)
 {
     int id = value->id;
     if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu)
-        return CSSPrimitiveValue::createIdentifier(id);
+        return p->primitiveValueCache()->createIdentifierValue(id);
 
     return p->parseColor(value);
 }
@@ -4988,7 +5000,7 @@ bool CSSParser::parseLinearGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea
     bool expectComma = false;
     // Look for angle.
     if (validUnit(a, FAngle, true)) {
-        result->setAngle(CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit));
+        result->setAngle(primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit));
         
         a = args->next();
         expectComma = true;
@@ -4998,7 +5010,7 @@ bool CSSParser::parseLinearGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea
         
         RefPtr<CSSPrimitiveValue> location;
         bool isHorizontal = false;
-        if ((location = valueFromSideKeyword(a, isHorizontal))) {
+        if ((location = valueFromSideKeyword(a, isHorizontal, primitiveValueCache()))) {
             if (isHorizontal)
                 startX = location;
             else
@@ -5006,7 +5018,7 @@ bool CSSParser::parseLinearGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea
             
             a = args->next();
             if (a) {
-                if ((location = valueFromSideKeyword(a, isHorizontal))) {
+                if ((location = valueFromSideKeyword(a, isHorizontal, primitiveValueCache()))) {
                     if (isHorizontal) {
                         if (startX)
                             return false;
@@ -5025,7 +5037,7 @@ bool CSSParser::parseLinearGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea
         }
         
         if (!startX && !startY)
-            startY = CSSPrimitiveValue::createIdentifier(CSSValueTop);
+            startY = primitiveValueCache()->createIdentifierValue(CSSValueTop);
             
         result->setFirstX(startX.release());
         result->setFirstY(startY.release());
@@ -5095,7 +5107,7 @@ bool CSSParser::parseRadialGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea
         switch (a->id) {
         case CSSValueCircle:
         case CSSValueEllipse:
-            shapeValue = CSSPrimitiveValue::createIdentifier(a->id);
+            shapeValue = primitiveValueCache()->createIdentifierValue(a->id);
             foundValue = true;
             break;
         case CSSValueClosestSide:
@@ -5104,7 +5116,7 @@ bool CSSParser::parseRadialGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea
         case CSSValueFarthestCorner:
         case CSSValueContain:
         case CSSValueCover:
-            sizeValue = CSSPrimitiveValue::createIdentifier(a->id);
+            sizeValue = primitiveValueCache()->createIdentifierValue(a->id);
             foundValue = true;
             break;
         }
@@ -5127,7 +5139,7 @@ bool CSSParser::parseRadialGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea
 
     if (!shapeValue && !sizeValue) {
         if (validUnit(a, FLength | FPercent, m_strict)) {
-            horizontalSize = CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
+            horizontalSize = primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
             a = args->next();
             if (!a)
                 return false;
@@ -5136,7 +5148,7 @@ bool CSSParser::parseRadialGradient(RefPtr<CSSValue>& gradient, CSSGradientRepea
         }
 
         if (validUnit(a, FLength | FPercent, m_strict)) {
-            verticalSize = CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
+            verticalSize = primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit);
 
             a = args->next();
             if (!a)
@@ -5184,7 +5196,7 @@ bool CSSParser::parseGradientColorStops(CSSParserValueList* valueList, CSSGradie
         a = valueList->next();
         if (a) {
             if (validUnit(a, FLength | FPercent, m_strict)) {
-                stop.m_position = CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit);
+                stop.m_position = primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes)a->unit);
                 a = valueList->next();
             }
         }
@@ -5405,7 +5417,7 @@ PassRefPtr<CSSValueList> CSSParser::parseTransform()
                 return 0;
 
             // Add the value to the current transform operation.
-            transformValue->append(CSSPrimitiveValue::create(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit));
+            transformValue->append(primitiveValueCache()->createValue(a->fValue, (CSSPrimitiveValue::UnitTypes) a->unit));
 
             a = args->next();
             if (!a)
@@ -5454,7 +5466,7 @@ bool CSSParser::parseTransformOrigin(int propId, int& propId1, int& propId2, int
         }
         case CSSPropertyWebkitTransformOriginZ: {
             if (validUnit(m_valueList->current(), FLength, m_strict))
-                value = CSSPrimitiveValue::create(m_valueList->current()->fValue, (CSSPrimitiveValue::UnitTypes)m_valueList->current()->unit);
+                value = primitiveValueCache()->createValue(m_valueList->current()->fValue, (CSSPrimitiveValue::UnitTypes)m_valueList->current()->unit);
             if (value)
                 m_valueList->next();
             break;
@@ -5507,7 +5519,7 @@ bool CSSParser::parseTextEmphasisStyle(bool important)
         if (value->unit == CSSPrimitiveValue::CSS_STRING) {
             if (fill || shape || (valueListSize != 1 && !inShorthand()))
                 return false;
-            addProperty(CSSPropertyWebkitTextEmphasisStyle, CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_STRING), important);
+            addProperty(CSSPropertyWebkitTextEmphasisStyle, primitiveValueCache()->createValue(value->string, CSSPrimitiveValue::CSS_STRING), important);
             m_valueList->next();
             return true;
         }
@@ -5515,7 +5527,7 @@ bool CSSParser::parseTextEmphasisStyle(bool important)
         if (value->id == CSSValueNone) {
             if (fill || shape || (valueListSize != 1 && !inShorthand()))
                 return false;
-            addProperty(CSSPropertyWebkitTextEmphasisStyle, CSSPrimitiveValue::createIdentifier(CSSValueNone), important);
+            addProperty(CSSPropertyWebkitTextEmphasisStyle, primitiveValueCache()->createIdentifierValue(CSSValueNone), important);
             m_valueList->next();
             return true;
         }
@@ -5523,11 +5535,11 @@ bool CSSParser::parseTextEmphasisStyle(bool important)
         if (value->id == CSSValueOpen || value->id == CSSValueFilled) {
             if (fill)
                 return false;
-            fill = CSSPrimitiveValue::createIdentifier(value->id);
+            fill = primitiveValueCache()->createIdentifierValue(value->id);
         } else if (value->id == CSSValueDot || value->id == CSSValueCircle || value->id == CSSValueDoubleCircle || value->id == CSSValueTriangle || value->id == CSSValueSesame) {
             if (shape)
                 return false;
-            shape = CSSPrimitiveValue::createIdentifier(value->id);
+            shape = primitiveValueCache()->createIdentifierValue(value->id);
         } else if (!inShorthand())
             return false;
         else
index 99b9c44..230e699 100644 (file)
@@ -38,6 +38,7 @@ namespace WebCore {
 
     class CSSMutableStyleDeclaration;
     class CSSPrimitiveValue;
+    class CSSPrimitiveValueCache;
     class CSSProperty;
     class CSSRule;
     class CSSRuleList;
@@ -70,6 +71,8 @@ namespace WebCore {
         bool parseMediaQuery(MediaList*, const String&);
 
         Document* document() const;
+    
+        CSSPrimitiveValueCache* primitiveValueCache() const { return m_primitiveValueCache.get(); }
 
         void addProperty(int propId, PassRefPtr<CSSValue>, bool important);
         void rollbackLastProperties(int num);
@@ -226,6 +229,7 @@ namespace WebCore {
         CSSParserValueList* m_valueList;
         CSSProperty** m_parsedProperties;
         CSSSelectorList* m_selectorListForParseSelector;
+        RefPtr<CSSPrimitiveValueCache> m_primitiveValueCache;
         unsigned m_numParsedProperties;
         unsigned m_maxParsedProperties;
         unsigned m_numParsedPropertiesBeforeMarginBox;
@@ -262,6 +266,8 @@ namespace WebCore {
         int lex();
 
     private:
+        void setStyleSheet(CSSStyleSheet*);
+        
         void recheckAtKeyword(const UChar* str, int len);
 
         void setupParser(const char* prefix, const String&, const char* suffix);
index 0f92e6d..04f1089 100644 (file)
@@ -87,103 +87,6 @@ static CSSTextCache& cssTextCache()
     return cache;
 }
 
-// A more stylish solution than sharing would be to turn CSSPrimitiveValue (or CSSValues in general) into non-virtual,
-// non-refcounted simple type with value semantics. In practice these sharing tricks get similar memory benefits
-// with less need for refactoring.
-
-inline PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createUncachedIdentifier(int identifier)
-{
-    return adoptRef(new CSSPrimitiveValue(identifier));
-}
-
-inline PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createUncachedColor(unsigned rgbValue)
-{
-    return adoptRef(new CSSPrimitiveValue(rgbValue));
-}
-
-inline PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createUncached(double value, UnitTypes type)
-{
-    return adoptRef(new CSSPrimitiveValue(value, type));
-}
-
-PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createIdentifier(int ident)
-{
-    static RefPtr<CSSPrimitiveValue>* identValueCache = new RefPtr<CSSPrimitiveValue>[numCSSValueKeywords];
-    if (ident >= 0 && ident < numCSSValueKeywords) {
-        RefPtr<CSSPrimitiveValue> primitiveValue = identValueCache[ident];
-        if (!primitiveValue) {
-            primitiveValue = createUncachedIdentifier(ident);
-            identValueCache[ident] = primitiveValue;
-        }
-        return primitiveValue.release();
-    } 
-    return createUncachedIdentifier(ident);
-}
-
-PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::createColor(unsigned rgbValue)
-{
-    typedef HashMap<unsigned, RefPtr<CSSPrimitiveValue> > ColorValueCache;
-    static ColorValueCache* colorValueCache = new ColorValueCache;
-    // These are the empty and deleted values of the hash table.
-    if (rgbValue == Color::transparent) {
-        static CSSPrimitiveValue* colorTransparent = createUncachedColor(Color::transparent).releaseRef();
-#if CPU(ARM) && OS(LINUX)
-         // A workaround for gcc bug on ARM.
-        if (!colorTransparent)
-            return 0;
-#endif
-        return colorTransparent;
-    }
-    if (rgbValue == Color::white) {
-        static CSSPrimitiveValue* colorWhite = createUncachedColor(Color::white).releaseRef();
-#if CPU(ARM) && OS(LINUX)
-        // A workaround for gcc bug on ARM.
-        if (!colorWhite)
-            return 0;
-#endif
-        return colorWhite;
-    }
-    RefPtr<CSSPrimitiveValue> primitiveValue = colorValueCache->get(rgbValue);
-    if (primitiveValue)
-        return primitiveValue.release();
-    primitiveValue = createUncachedColor(rgbValue);
-    // Just wipe out the cache and start rebuilding when it gets too big.
-    const int maxColorCacheSize = 512;
-    if (colorValueCache->size() >= maxColorCacheSize)
-        colorValueCache->clear();
-    colorValueCache->add(rgbValue, primitiveValue);
-    
-    return primitiveValue.release();
-}
-
-PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::create(double value, UnitTypes type)
-{
-    // Small integers are very common. Try to share them.
-    const int cachedIntegerCount = 128;
-    // Other common primitive types have UnitTypes smaller than this.
-    const int maxCachedUnitType = CSS_PX;
-    typedef RefPtr<CSSPrimitiveValue>(* IntegerValueCache)[maxCachedUnitType + 1];
-    static IntegerValueCache integerValueCache = new RefPtr<CSSPrimitiveValue>[cachedIntegerCount][maxCachedUnitType + 1];
-    if (type <= maxCachedUnitType && value >= 0 && value < cachedIntegerCount) {
-        int intValue = static_cast<int>(value);
-        if (value == intValue) {
-            RefPtr<CSSPrimitiveValue> primitiveValue = integerValueCache[intValue][type];
-            if (!primitiveValue) {
-                primitiveValue = createUncached(value, type);
-                integerValueCache[intValue][type] = primitiveValue;
-            }
-            return primitiveValue.release();
-        }
-    }
-
-    return createUncached(value, type);
-}
-
-PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValue::create(const String& value, UnitTypes type)
-{
-    return adoptRef(new CSSPrimitiveValue(value, type));
-}
-
 static const AtomicString& valueOrPropertyName(int valueOrPropertyID)
 {
     ASSERT_ARG(valueOrPropertyID, valueOrPropertyID >= 0);
index 35a3fdf..499e95c 100644 (file)
@@ -110,10 +110,10 @@ public:
     static bool isUnitTypeLength(int type) { return (type > CSSPrimitiveValue::CSS_PERCENTAGE && type < CSSPrimitiveValue::CSS_DEG) ||
                                                     type == CSSPrimitiveValue::CSS_REMS; }
 
-    static PassRefPtr<CSSPrimitiveValue> createIdentifier(int ident);
-    static PassRefPtr<CSSPrimitiveValue> createColor(unsigned rgbValue);
-    static PassRefPtr<CSSPrimitiveValue> create(double value, UnitTypes type);
-    static PassRefPtr<CSSPrimitiveValue> create(const String& value, UnitTypes type);
+    static PassRefPtr<CSSPrimitiveValue> createIdentifier(int identifier) { return adoptRef(new CSSPrimitiveValue(identifier)); }
+    static PassRefPtr<CSSPrimitiveValue> createColor(unsigned rgbValue) { return adoptRef(new CSSPrimitiveValue(rgbValue)); }
+    static PassRefPtr<CSSPrimitiveValue> create(double value, UnitTypes type) { return adoptRef(new CSSPrimitiveValue(value, type)); }
+    static PassRefPtr<CSSPrimitiveValue> create(const String& value, UnitTypes type) { return adoptRef(new CSSPrimitiveValue(value, type)); }
     
     template<typename T> static PassRefPtr<CSSPrimitiveValue> create(T value)
     {
diff --git a/Source/WebCore/css/CSSPrimitiveValueCache.cpp b/Source/WebCore/css/CSSPrimitiveValueCache.cpp
new file mode 100644 (file)
index 0000000..69fd555
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+#include "CSSPrimitiveValueCache.h"
+
+namespace WebCore {
+
+CSSPrimitiveValueCache::CSSPrimitiveValueCache()
+    : m_colorTransparent(CSSPrimitiveValue::createColor(Color::transparent))
+    , m_colorWhite(CSSPrimitiveValue::createColor(Color::white))
+    , m_colorBlack(CSSPrimitiveValue::createColor(Color::black))
+{
+}
+
+CSSPrimitiveValueCache::~CSSPrimitiveValueCache()
+{
+}
+
+PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValueCache::createIdentifierValue(int ident)
+{
+    if (ident < 0 || ident >= numCSSValueKeywords)
+        return CSSPrimitiveValue::createIdentifier(ident);
+
+    RefPtr<CSSPrimitiveValue> primitiveValue = m_identifierValueCache[ident];
+    if (!primitiveValue) {
+        primitiveValue = CSSPrimitiveValue::createIdentifier(ident);
+        m_identifierValueCache[ident] = primitiveValue;
+    }
+    return primitiveValue.release();
+}
+
+PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValueCache::createColorValue(unsigned rgbValue)
+{
+    // These are the empty and deleted values of the hash table.
+    if (rgbValue == Color::transparent)
+        return m_colorTransparent;
+    if (rgbValue == Color::white)
+        return m_colorWhite;
+    // Just because it is common.
+    if (rgbValue == Color::black)
+        return m_colorBlack;    
+
+    RefPtr<CSSPrimitiveValue> primitiveValue = m_colorValueCache.get(rgbValue);
+    if (primitiveValue)
+        return primitiveValue.release();
+    primitiveValue = CSSPrimitiveValue::createColor(rgbValue);
+    // Just wipe out the cache and start rebuilding if it gets too big.
+    const int maxColorCacheSize = 512;
+    if (m_colorValueCache.size() >= maxColorCacheSize)
+        m_colorValueCache.clear();
+    m_colorValueCache.add(rgbValue, primitiveValue);
+    
+    return primitiveValue.release();
+}
+
+PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValueCache::createValue(double value, CSSPrimitiveValue::UnitTypes type)
+{
+    if (type > maxCachedUnitType || value < 0 || value >= cachedIntegerCount)
+        return CSSPrimitiveValue::create(value, type);
+
+    int intValue = static_cast<int>(value);
+    if (value != intValue)
+        return CSSPrimitiveValue::create(value, type);
+    RefPtr<CSSPrimitiveValue> primitiveValue = m_integerValueCache[intValue][type];
+    if (!primitiveValue) {
+        primitiveValue = CSSPrimitiveValue::create(value, type);
+        m_integerValueCache[intValue][type] = primitiveValue;
+    }
+    return primitiveValue.release();
+}
+
+}
diff --git a/Source/WebCore/css/CSSPrimitiveValueCache.h b/Source/WebCore/css/CSSPrimitiveValueCache.h
new file mode 100644 (file)
index 0000000..93c19fc
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef CSSPrimitiveValueCache_h
+#define CSSPrimitiveValueCache_h
+
+#include "CSSPrimitiveValue.h"
+#include "CSSValueKeywords.h"
+#include <wtf/HashMap.h>
+#include <wtf/RefPtr.h>
+
+namespace WebCore {
+    
+class CSSPrimitiveValue;
+
+class CSSPrimitiveValueCache : public RefCounted<CSSPrimitiveValueCache> {
+public:
+    static PassRefPtr<CSSPrimitiveValueCache> create() { return adoptRef(new CSSPrimitiveValueCache); }
+    ~CSSPrimitiveValueCache();
+
+    PassRefPtr<CSSPrimitiveValue> createIdentifierValue(int identifier);
+    PassRefPtr<CSSPrimitiveValue> createColorValue(unsigned rgbValue);
+    PassRefPtr<CSSPrimitiveValue> createValue(double value, CSSPrimitiveValue::UnitTypes);
+    PassRefPtr<CSSPrimitiveValue> createValue(String value, CSSPrimitiveValue::UnitTypes type) { return CSSPrimitiveValue::create(value, type); }
+    template<typename T> static PassRefPtr<CSSPrimitiveValue> createValue(T value) { return CSSPrimitiveValue::create(value); }
+    
+private:
+    CSSPrimitiveValueCache();
+
+    typedef RefPtr<CSSPrimitiveValue> IdentifierValueCache[numCSSValueKeywords];
+    IdentifierValueCache m_identifierValueCache;
+
+    typedef HashMap<unsigned, RefPtr<CSSPrimitiveValue> > ColorValueCache;
+    ColorValueCache m_colorValueCache;
+    RefPtr<CSSPrimitiveValue> m_colorTransparent;
+    RefPtr<CSSPrimitiveValue> m_colorWhite;
+    RefPtr<CSSPrimitiveValue> m_colorBlack;
+    
+    // Small integers are very common. Share them.
+    static const int cachedIntegerCount = 128;
+    // Other common primitive types have UnitTypes smaller than this.
+    static const int maxCachedUnitType = CSSPrimitiveValue::CSS_PX;
+    typedef RefPtr<CSSPrimitiveValue> IntegerValueCache[cachedIntegerCount][maxCachedUnitType + 1];
+    IntegerValueCache m_integerValueCache;
+};
+
+}
+
+#endif
index ca768d0..8d1011c 100644 (file)
@@ -33,6 +33,7 @@
 #include "Attr.h"
 #include "Attribute.h"
 #include "CDATASection.h"
+#include "CSSPrimitiveValueCache.h"
 #include "CSSStyleSelector.h"
 #include "CSSStyleSheet.h"
 #include "CSSValueKeywords.h"
@@ -1698,6 +1699,13 @@ void Document::pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int&
     marginLeft = style->marginLeft().isAuto() ? marginLeft : style->marginLeft().calcValue(width);
 }
 
+PassRefPtr<CSSPrimitiveValueCache> Document::cssPrimitiveValueCache() const
+{
+    if (!m_cssPrimitiveValueCache)
+        m_cssPrimitiveValueCache = CSSPrimitiveValueCache::create();
+    return m_cssPrimitiveValueCache;
+}
+
 void Document::createStyleSelector()
 {
     bool matchAuthorAndUserStyles = true;
index d565e3e..db04cc1 100644 (file)
@@ -60,6 +60,7 @@ class CachedResourceLoader;
 class CachedScript;
 class CanvasRenderingContext;
 class CharacterData;
+class CSSPrimitiveValueCache;
 class CSSStyleDeclaration;
 class CSSStyleSelector;
 class CSSStyleSheet;
@@ -434,6 +435,8 @@ public:
 #endif
     virtual bool isFrameSet() const { return false; }
     
+    PassRefPtr<CSSPrimitiveValueCache> cssPrimitiveValueCache() const;
+    
     CSSStyleSelector* styleSelectorIfExists() const { return m_styleSelector.get(); }
 
     bool usesViewSourceStyles() const { return m_usesViewSourceStyles; }
@@ -1168,6 +1171,8 @@ private:
     OwnPtr<CSSStyleSelector> m_styleSelector;
     bool m_didCalculateStyleSelector;
     bool m_hasDirtyStyleSelector;
+    
+    mutable RefPtr<CSSPrimitiveValueCache> m_cssPrimitiveValueCache;
 
     Frame* m_frame;
     DocumentLoader* m_documentLoader;