Title: [109829] trunk/Source/WebCore
Revision
109829
Author
[email protected]
Date
2012-03-05 17:51:01 -0800 (Mon, 05 Mar 2012)

Log Message

[JSC] Cache the CSSPropertyID in JSCSSStyleDeclaration
https://bugs.webkit.org/show_bug.cgi?id=80250

Reviewed by Benjamin Poulain.

V8CSSStyleDeclaration caches the calculated CSSPropertyID.
Similarly, we can implement the cache in JSCSSStyleDeclaration.

In my local Mac environment, this optimization improves the performance
of CSS property getters by 35%, and the performance of CSS property setters
by 8%.

CSS property getter: for (var i = 0; i < 1000000; i++) span.style.fontWeight;
CSS property setter: for (var i = 0; i < 1000000; i++) span.style.fontWeight = "bold";

Tests: fast/dom/CSSStyleDeclaration/* (No change in test results)

* bindings/js/JSCSSStyleDeclarationCustom.cpp:
(CSSPropertyInfo):
(WebCore):
(WebCore::cssPropertyIDForJSCSSPropertyName):
(WebCore::JSCSSStyleDeclaration::nameGetter):
(WebCore::JSCSSStyleDeclaration::putDelegate):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (109828 => 109829)


--- trunk/Source/WebCore/ChangeLog	2012-03-06 01:41:54 UTC (rev 109828)
+++ trunk/Source/WebCore/ChangeLog	2012-03-06 01:51:01 UTC (rev 109829)
@@ -1,3 +1,29 @@
+2012-03-05  Kentaro Hara  <[email protected]>
+
+        [JSC] Cache the CSSPropertyID in JSCSSStyleDeclaration
+        https://bugs.webkit.org/show_bug.cgi?id=80250
+
+        Reviewed by Benjamin Poulain.
+
+        V8CSSStyleDeclaration caches the calculated CSSPropertyID.
+        Similarly, we can implement the cache in JSCSSStyleDeclaration.
+
+        In my local Mac environment, this optimization improves the performance
+        of CSS property getters by 35%, and the performance of CSS property setters
+        by 8%.
+
+        CSS property getter: for (var i = 0; i < 1000000; i++) span.style.fontWeight;
+        CSS property setter: for (var i = 0; i < 1000000; i++) span.style.fontWeight = "bold";
+
+        Tests: fast/dom/CSSStyleDeclaration/* (No change in test results)
+
+        * bindings/js/JSCSSStyleDeclarationCustom.cpp:
+        (CSSPropertyInfo):
+        (WebCore):
+        (WebCore::cssPropertyIDForJSCSSPropertyName):
+        (WebCore::JSCSSStyleDeclaration::nameGetter):
+        (WebCore::JSCSSStyleDeclaration::putDelegate):
+
 2012-03-05  Joshua Bell  <[email protected]>
 
         IndexedDB: Handle LevelDB database corruption

Modified: trunk/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp (109828 => 109829)


--- trunk/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp	2012-03-06 01:41:54 UTC (rev 109828)
+++ trunk/Source/WebCore/bindings/js/JSCSSStyleDeclarationCustom.cpp	2012-03-06 01:51:01 UTC (rev 109829)
@@ -58,6 +58,12 @@
     visitor.addOpaqueRoot(root(thisObject->impl()));
 }
 
+class CSSPropertyInfo {
+public:
+    int propertyID;
+    bool hadPixelOrPosPrefix;
+};
+
 enum PropertyNamePrefix
 {
     PropertyNamePrefixNone,
@@ -161,16 +167,23 @@
     *buffer++ = '-';
 }
 
-static int cssPropertyIDForJSCSSPropertyName(const Identifier& propertyName, bool* hadPixelOrPosPrefix = 0)
+static CSSPropertyInfo cssPropertyIDForJSCSSPropertyName(const Identifier& propertyName)
 {
-    if (hadPixelOrPosPrefix)
-        *hadPixelOrPosPrefix = false;
+    CSSPropertyInfo propertyInfo = {0, false};
+    bool hadPixelOrPosPrefix = false;
 
     unsigned length = propertyName.length();
     if (!length)
-        return 0;
+        return propertyInfo;
 
     StringImpl* propertyNameString = propertyName.impl();
+    String stringForCache = String(propertyNameString);
+    typedef HashMap<String, CSSPropertyInfo> CSSPropertyInfoMap;
+    DEFINE_STATIC_LOCAL(CSSPropertyInfoMap, propertyInfoCache, ());
+    propertyInfo = propertyInfoCache.get(stringForCache);
+    if (propertyInfo.propertyID)
+        return propertyInfo;
+
     const size_t bufferSize = maxCSSPropertyNameLength + 1;
     char buffer[bufferSize];
     char* bufferPtr = buffer;
@@ -183,20 +196,18 @@
     switch (getCSSPropertyNamePrefix(*propertyNameString)) {
     case PropertyNamePrefixNone:
         if (isASCIIUpper((*propertyNameString)[0]))
-            return 0;
+            return propertyInfo;
         break;
     case PropertyNamePrefixCSS:
         i += 3;
         break;
     case PropertyNamePrefixPixel:
         i += 5;
-        if (hadPixelOrPosPrefix)
-            *hadPixelOrPosPrefix = true;
+        hadPixelOrPosPrefix = true;
         break;
     case PropertyNamePrefixPos:
         i += 3;
-        if (hadPixelOrPosPrefix)
-            *hadPixelOrPosPrefix = true;
+        hadPixelOrPosPrefix = true;
         break;
     case PropertyNamePrefixApple:
     case PropertyNamePrefixKHTML:
@@ -220,17 +231,17 @@
     size_t bufferSizeLeft = stringEnd - bufferPtr;
     size_t propertySizeLeft = length - i;
     if (propertySizeLeft > bufferSizeLeft)
-        return 0;
+        return propertyInfo;
 
     for (; i < length; ++i) {
         UChar c = (*propertyNameString)[i];
         if (!c || c >= 0x7F)
-            return 0; // illegal character
+            return propertyInfo; // illegal character
         if (isASCIIUpper(c)) {
             size_t bufferSizeLeft = stringEnd - bufferPtr;
             size_t propertySizeLeft = length - i + 1;
             if (propertySizeLeft > bufferSizeLeft)
-                return 0;
+                return propertyInfo;
             *bufferPtr++ = '-';
             *bufferPtr++ = toASCIILower(c);
         } else
@@ -246,12 +257,19 @@
 #endif
 
     const Property* hashTableEntry = findProperty(name, outputLength);
-    return hashTableEntry ? hashTableEntry->id : 0;
+    int propertyID = hashTableEntry ? hashTableEntry->id : 0;
+    if (propertyID) {
+        propertyInfo.hadPixelOrPosPrefix = hadPixelOrPosPrefix;
+        propertyInfo.propertyID = propertyID;
+        propertyInfoCache.add(stringForCache, propertyInfo);
+    }
+    return propertyInfo;
 }
 
 static bool isCSSPropertyName(const Identifier& propertyIdentifier)
 {
-    return cssPropertyIDForJSCSSPropertyName(propertyIdentifier);
+    CSSPropertyInfo propertyInfo = cssPropertyIDForJSCSSPropertyName(propertyIdentifier);
+    return propertyInfo.propertyID;
 }
 
 bool JSCSSStyleDeclaration::canGetItemsForName(ExecState*, CSSStyleDeclaration*, const Identifier& propertyName)
@@ -268,32 +286,30 @@
     // posTop returns "CSS top" as number value in unit pixels _if_ its a
     // positioned element. if it is not a positioned element, return 0
     // from MSIE documentation FIXME: IMPLEMENT THAT (Dirk)
-    bool pixelOrPos;
-    int cssPropertyID = cssPropertyIDForJSCSSPropertyName(propertyName, &pixelOrPos);
-    RefPtr<CSSValue> v = thisObj->impl()->getPropertyCSSValueInternal(static_cast<CSSPropertyID>(cssPropertyID));
+    CSSPropertyInfo propertyInfo = cssPropertyIDForJSCSSPropertyName(propertyName);
+    RefPtr<CSSValue> v = thisObj->impl()->getPropertyCSSValueInternal(static_cast<CSSPropertyID>(propertyInfo.propertyID));
     if (v) {
-        if (pixelOrPos && v->isPrimitiveValue())
+        if (propertyInfo.hadPixelOrPosPrefix && v->isPrimitiveValue())
             return jsNumber(static_pointer_cast<CSSPrimitiveValue>(v)->getFloatValue(CSSPrimitiveValue::CSS_PX));
         return jsStringOrNull(exec, v->cssText());
     }
 
     // If the property is a shorthand property (such as "padding"), 
     // it can only be accessed using getPropertyValue.
-    return jsString(exec, thisObj->impl()->getPropertyValueInternal(static_cast<CSSPropertyID>(cssPropertyID)));
+    return jsString(exec, thisObj->impl()->getPropertyValueInternal(static_cast<CSSPropertyID>(propertyInfo.propertyID)));
 }
 
 bool JSCSSStyleDeclaration::putDelegate(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot&)
 {
-    bool pixelOrPos;
-    int cssPropertyID = cssPropertyIDForJSCSSPropertyName(propertyName, &pixelOrPos);
-    if (!cssPropertyID)
+    CSSPropertyInfo propertyInfo = cssPropertyIDForJSCSSPropertyName(propertyName);
+    if (!propertyInfo.propertyID)
         return false;
 
     String propValue = valueToStringWithNullCheck(exec, value);
-    if (pixelOrPos)
+    if (propertyInfo.hadPixelOrPosPrefix)
         propValue += "px";
     ExceptionCode ec = 0;
-    impl()->setPropertyInternal(static_cast<CSSPropertyID>(cssPropertyID), propValue, false, ec);
+    impl()->setPropertyInternal(static_cast<CSSPropertyID>(propertyInfo.propertyID), propValue, false, ec);
     setDOMException(exec, ec);
     return true;
 }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to