Bug 559715: Micro-optimize nsCSSPropertySet by adjusting types so that the compiler can do index calculations more efficiently., r=dbaron, a=dholbert_sheriff
authorZack Weinberg <zweinberg@mozilla.com>
Fri, 23 Apr 2010 12:59:15 -0700
changeset 41215 11b94fd7854864178f0a3842fa50fd1c1826ed55
parent 41214 426165b08c0c4b5d952d775c9e5981713b05881a
child 41216 bd5f3bf5c5115aae7b4fbb263a150b6e64155162
push idunknown
push userunknown
push dateunknown
reviewersdbaron, dholbert_sheriff
bugs559715
milestone1.9.3a5pre
Bug 559715: Micro-optimize nsCSSPropertySet by adjusting types so that the compiler can do index calculations more efficiently., r=dbaron, a=dholbert_sheriff
layout/style/nsCSSDataBlock.cpp
layout/style/nsCSSPropertySet.h
--- a/layout/style/nsCSSDataBlock.cpp
+++ b/layout/style/nsCSSDataBlock.cpp
@@ -709,20 +709,20 @@ nsCSSExpandedDataBlock::Expand(
         DoExpand(aImportantBlock, PR_TRUE);
     }
 }
 
 nsCSSExpandedDataBlock::ComputeSizeResult
 nsCSSExpandedDataBlock::ComputeSize()
 {
     ComputeSizeResult result = {0, 0};
-    for (PRUint32 iHigh = 0; iHigh < nsCSSPropertySet::kChunkCount; ++iHigh) {
+    for (size_t iHigh = 0; iHigh < nsCSSPropertySet::kChunkCount; ++iHigh) {
         if (!mPropertiesSet.HasPropertyInChunk(iHigh))
             continue;
-        for (PRInt32 iLow = 0; iLow < nsCSSPropertySet::kBitsInChunk; ++iLow) {
+        for (size_t iLow = 0; iLow < nsCSSPropertySet::kBitsInChunk; ++iLow) {
             if (!mPropertiesSet.HasPropertyAt(iHigh, iLow))
                 continue;
             nsCSSProperty iProp = nsCSSPropertySet::CSSPropertyAt(iHigh, iLow);
             NS_ASSERTION(0 <= iProp && iProp < eCSSProperty_COUNT_no_shorthands,
                          "out of range");
 #ifdef DEBUG
             void *prop = PropertyAt(iProp);
 #endif
@@ -803,20 +803,20 @@ nsCSSExpandedDataBlock::Compress(nsCSSCo
         result_important = nsnull;
     }
 
     /*
      * Save needless copying and allocation by copying the memory
      * corresponding to the stored data in the expanded block, and then
      * clearing the data in the expanded block.
      */
-    for (PRUint32 iHigh = 0; iHigh < nsCSSPropertySet::kChunkCount; ++iHigh) {
+    for (size_t iHigh = 0; iHigh < nsCSSPropertySet::kChunkCount; ++iHigh) {
         if (!mPropertiesSet.HasPropertyInChunk(iHigh))
             continue;
-        for (PRInt32 iLow = 0; iLow < nsCSSPropertySet::kBitsInChunk; ++iLow) {
+        for (size_t iLow = 0; iLow < nsCSSPropertySet::kBitsInChunk; ++iLow) {
             if (!mPropertiesSet.HasPropertyAt(iHigh, iLow))
                 continue;
             nsCSSProperty iProp = nsCSSPropertySet::CSSPropertyAt(iHigh, iLow);
             NS_ASSERTION(0 <= iProp && iProp < eCSSProperty_COUNT_no_shorthands,
                          "out of range");
             void *prop = PropertyAt(iProp);
             PRBool important =
                 mPropertiesImportant.HasPropertyAt(iHigh, iLow);
@@ -891,20 +891,20 @@ nsCSSExpandedDataBlock::Compress(nsCSSCo
     AssertInitialState();
     result_normal.forget(aNormalBlock);
     result_important.forget(aImportantBlock);
 }
 
 void
 nsCSSExpandedDataBlock::Clear()
 {
-    for (PRUint32 iHigh = 0; iHigh < nsCSSPropertySet::kChunkCount; ++iHigh) {
+    for (size_t iHigh = 0; iHigh < nsCSSPropertySet::kChunkCount; ++iHigh) {
         if (!mPropertiesSet.HasPropertyInChunk(iHigh))
             continue;
-        for (PRInt32 iLow = 0; iLow < nsCSSPropertySet::kBitsInChunk; ++iLow) {
+        for (size_t iLow = 0; iLow < nsCSSPropertySet::kBitsInChunk; ++iLow) {
             if (!mPropertiesSet.HasPropertyAt(iHigh, iLow))
                 continue;
             nsCSSProperty iProp = nsCSSPropertySet::CSSPropertyAt(iHigh, iLow);
             ClearProperty(iProp);
         }
     }
 
     AssertInitialState();
--- a/layout/style/nsCSSPropertySet.h
+++ b/layout/style/nsCSSPropertySet.h
@@ -35,16 +35,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 /* bit vectors for sets of CSS properties */
 
 #ifndef nsCSSPropertySet_h__
 #define nsCSSPropertySet_h__
 
 #include "nsCSSProperty.h"
+#include <limits.h> // for CHAR_BIT
 
 /**
  * nsCSSPropertySet maintains a set of non-shorthand CSS properties.  In
  * other words, for each longhand CSS property we support, it has a bit
  * for whether that property is in the set.
  */
 class nsCSSPropertySet {
 public:
@@ -52,66 +53,71 @@ public:
     // auto-generated copy-constructor OK
 
     void AssertInSetRange(nsCSSProperty aProperty) const {
         NS_ASSERTION(0 <= aProperty &&
                      aProperty < eCSSProperty_COUNT_no_shorthands,
                      "out of bounds");
     }
 
+    // Conversion of aProperty to |size_t| after AssertInSetRange
+    // lets the compiler generate significantly tighter code.
+
     void AddProperty(nsCSSProperty aProperty) {
         AssertInSetRange(aProperty);
-        mProperties[aProperty / kBitsInChunk] |=
-            property_set_type(1 << (aProperty % kBitsInChunk));
+        size_t p = aProperty;
+        mProperties[p / kBitsInChunk] |=
+          property_set_type(1) << (p % kBitsInChunk);
     }
 
     void RemoveProperty(nsCSSProperty aProperty) {
         AssertInSetRange(aProperty);
-        mProperties[aProperty / kBitsInChunk] &=
-            ~property_set_type(1 << (aProperty % kBitsInChunk));
+        size_t p = aProperty;
+        mProperties[p / kBitsInChunk] &=
+            ~(property_set_type(1) << (p % kBitsInChunk));
     }
 
-    PRBool HasProperty(nsCSSProperty aProperty) const {
+    bool HasProperty(nsCSSProperty aProperty) const {
         AssertInSetRange(aProperty);
-        return (mProperties[aProperty / kBitsInChunk] &
-                (1 << (aProperty % kBitsInChunk))) != 0;
+        size_t p = aProperty;
+        return (mProperties[p / kBitsInChunk] &
+                (property_set_type(1) << (p % kBitsInChunk))) != 0;
     }
 
     void Empty() {
         memset(mProperties, 0, sizeof(mProperties));
     }
 
     void AssertIsEmpty(const char* aText) const {
-        for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(mProperties); ++i) {
+        for (size_t i = 0; i < NS_ARRAY_LENGTH(mProperties); ++i) {
             NS_ASSERTION(mProperties[i] == 0, aText);
         }
     }
 
 private:
-    typedef PRUint8 property_set_type;
+    typedef unsigned long property_set_type;
 public:
-    enum { kBitsInChunk = 8 }; // number of bits in
-                                          // |property_set_type|.
+    // number of bits in |property_set_type|.
+    static const size_t kBitsInChunk = sizeof(property_set_type)*CHAR_BIT;
     // number of |property_set_type|s in the set
-    enum { kChunkCount =
-             (eCSSProperty_COUNT_no_shorthands + (kBitsInChunk-1)) /
-             kBitsInChunk };
+    static const size_t kChunkCount =
+        (eCSSProperty_COUNT_no_shorthands + kBitsInChunk - 1) / kBitsInChunk;
 
     /*
      * For fast enumeration of all the bits that are set, callers can
      * check each chunk against zero (since in normal cases few bits are
      * likely to be set).
      */
-    PRBool HasPropertyInChunk(PRUint32 aChunk) const {
+    bool HasPropertyInChunk(size_t aChunk) const {
         return mProperties[aChunk] != 0;
     }
-    PRBool HasPropertyAt(PRUint32 aChunk, PRInt32 aBit) const {
-        return (mProperties[aChunk] & (1 << aBit)) != 0;
+    bool HasPropertyAt(size_t aChunk, size_t aBit) const {
+        return (mProperties[aChunk] & (property_set_type(1) << aBit)) != 0;
     }
-    static nsCSSProperty CSSPropertyAt(PRUint32 aChunk, PRInt32 aBit) {
+    static nsCSSProperty CSSPropertyAt(size_t aChunk, size_t aBit) {
         return nsCSSProperty(aChunk * kBitsInChunk + aBit);
     }
 
 private:
     property_set_type mProperties[kChunkCount];
 };
 
 #endif /* !defined(nsCSSPropertySet_h__) */