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