Commit 204ccd37 authored by Nicholas Nethercote's avatar Nicholas Nethercote
Browse files

Backed out changeset c880f229fbf5 (bug 712865) due to build bustage. r=me.

parent f62f7cea
Loading
Loading
Loading
Loading
+120 −46
Original line number Original line Diff line number Diff line
@@ -48,6 +48,34 @@


namespace css = mozilla::css;
namespace css = mozilla::css;


enum {
    CDBValueStorage_advance = sizeof(CDBValueStorage)
};

/*
 * Define a bunch of utility functions for getting the property or any
 * of the value types when the cursor is at the beginning of the storage
 * for the property-value pair.  The versions taking a non-const cursor
 * argument return a reference so that the caller can assign into the
 * result.
 */

inline nsCSSProperty& PropertyAtCursor(char *aCursor) {
    return *reinterpret_cast<nsCSSProperty*>(aCursor);
}

inline nsCSSProperty PropertyAtCursor(const char *aCursor) {
    return *reinterpret_cast<const nsCSSProperty*>(aCursor);
}

inline nsCSSValue* ValueAtCursor(char *aCursor) {
    return & reinterpret_cast<CDBValueStorage*>(aCursor)->value;
}

inline const nsCSSValue* ValueAtCursor(const char *aCursor) {
    return & reinterpret_cast<const CDBValueStorage*>(aCursor)->value;
}

/**
/**
 * Does a fast move of aSource to aDest.  The previous value in
 * Does a fast move of aSource to aDest.  The previous value in
 * aDest is cleanly destroyed, and aSource is cleared.  Returns
 * aDest is cleanly destroyed, and aSource is cleared.  Returns
@@ -136,13 +164,16 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const


    nsIDocument* doc = aRuleData->mPresContext->Document();
    nsIDocument* doc = aRuleData->mPresContext->Document();


    for (PRUint32 i = 0; i < mNumProps; i++) {
    const char* cursor = Block();
        nsCSSProperty iProp = PropertyAtIndex(i);
    const char* cursor_end = BlockEnd();
    while (cursor < cursor_end) {
        nsCSSProperty iProp = PropertyAtCursor(cursor);
        NS_ABORT_IF_FALSE(!nsCSSProps::IsShorthand(iProp), "out of range");
        if (nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[iProp]) &
        if (nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[iProp]) &
            aRuleData->mSIDs) {
            aRuleData->mSIDs) {
            nsCSSValue* target = aRuleData->ValueFor(iProp);
            nsCSSValue* target = aRuleData->ValueFor(iProp);
            if (target->GetUnit() == eCSSUnit_Null) {
            if (target->GetUnit() == eCSSUnit_Null) {
                const nsCSSValue *val = ValueAtIndex(i);
                const nsCSSValue *val = ValueAtCursor(cursor);
                NS_ABORT_IF_FALSE(val->GetUnit() != eCSSUnit_Null, "oops");
                NS_ABORT_IF_FALSE(val->GetUnit() != eCSSUnit_Null, "oops");
                if (ShouldStartImageLoads(aRuleData, iProp)) {
                if (ShouldStartImageLoads(aRuleData, iProp)) {
                    TryToStartImageLoad(*val, doc, iProp);
                    TryToStartImageLoad(*val, doc, iProp);
@@ -166,7 +197,9 @@ nsCSSCompressedDataBlock::MapRuleInfoInto(nsRuleData *aRuleData) const
                }
                }
            }
            }
        }
        }
        cursor += CDBValueStorage_advance;
    }
    }
    NS_ABORT_IF_FALSE(cursor == cursor_end, "inconsistent data");
}
}


const nsCSSValue*
const nsCSSValue*
@@ -183,11 +216,17 @@ nsCSSCompressedDataBlock::ValueFor(nsCSSProperty aProperty) const
          mStyleBits))
          mStyleBits))
        return nsnull;
        return nsnull;


    for (PRUint32 i = 0; i < mNumProps; i++) {
    const char* cursor = Block();
        if (PropertyAtIndex(i) == aProperty) {
    const char* cursor_end = BlockEnd();
            return ValueAtIndex(i);
    while (cursor < cursor_end) {
        nsCSSProperty iProp = PropertyAtCursor(cursor);
        NS_ABORT_IF_FALSE(!nsCSSProps::IsShorthand(iProp), "out of range");
        if (iProp == aProperty) {
            return ValueAtCursor(cursor);
        }
        }
        cursor += CDBValueStorage_advance;
    }
    }
    NS_ABORT_IF_FALSE(cursor == cursor_end, "inconsistent data");


    return nsnull;
    return nsnull;
}
}
@@ -215,35 +254,56 @@ nsCSSCompressedDataBlock::TryReplaceValue(nsCSSProperty aProperty,
nsCSSCompressedDataBlock*
nsCSSCompressedDataBlock*
nsCSSCompressedDataBlock::Clone() const
nsCSSCompressedDataBlock::Clone() const
{
{
    nsAutoPtr<nsCSSCompressedDataBlock>
    const char *cursor = Block(), *cursor_end = BlockEnd();
        result(new(mNumProps) nsCSSCompressedDataBlock(mNumProps));
    char *result_cursor;


    result->mStyleBits = mStyleBits;
    nsAutoPtr<nsCSSCompressedDataBlock> result
        (new(cursor_end - cursor) nsCSSCompressedDataBlock());
    if (!result)
        return nsnull;
    result_cursor = result->Block();


    for (PRUint32 i = 0; i < mNumProps; i++) {
    while (cursor < cursor_end) {
        result->SetPropertyAtIndex(i, PropertyAtIndex(i));
        nsCSSProperty iProp = PropertyAtCursor(cursor);
        result->CopyValueToIndex(i, ValueAtIndex(i));
        NS_ABORT_IF_FALSE(!nsCSSProps::IsShorthand(iProp), "out of range");
        PropertyAtCursor(result_cursor) = iProp;

        const nsCSSValue* val = ValueAtCursor(cursor);
        nsCSSValue *result_val = ValueAtCursor(result_cursor);
        new (result_val) nsCSSValue(*val);
        cursor += CDBValueStorage_advance;
        result_cursor +=  CDBValueStorage_advance;
    }
    }
    NS_ABORT_IF_FALSE(cursor == cursor_end, "inconsistent data");

    result->SetBlockEnd(result_cursor);
    result->mStyleBits = mStyleBits;
    NS_ABORT_IF_FALSE(result->DataSize() == DataSize(), "wrong size");


    return result.forget();
    return result.forget();
}
}


nsCSSCompressedDataBlock::~nsCSSCompressedDataBlock()
nsCSSCompressedDataBlock::~nsCSSCompressedDataBlock()
{
{
    for (PRUint32 i = 0; i < mNumProps; i++) {
    const char* cursor = Block();
#ifdef DEBUG
    const char* cursor_end = BlockEnd();
        (void)PropertyAtIndex(i);   // this checks the property is in range
    while (cursor < cursor_end) {
#endif
        NS_ABORT_IF_FALSE(!nsCSSProps::IsShorthand(PropertyAtCursor(cursor)),
        const nsCSSValue* val = ValueAtIndex(i);
                          "out of range");

        const nsCSSValue* val = ValueAtCursor(cursor);
        NS_ABORT_IF_FALSE(val->GetUnit() != eCSSUnit_Null, "oops");
        NS_ABORT_IF_FALSE(val->GetUnit() != eCSSUnit_Null, "oops");
        val->~nsCSSValue();
        val->~nsCSSValue();
        cursor += CDBValueStorage_advance;
    }
    }
    NS_ABORT_IF_FALSE(cursor == cursor_end, "inconsistent data");
}
}


/* static */ nsCSSCompressedDataBlock*
/* static */ nsCSSCompressedDataBlock*
nsCSSCompressedDataBlock::CreateEmptyBlock()
nsCSSCompressedDataBlock::CreateEmptyBlock()
{
{
    nsCSSCompressedDataBlock *result = new(0) nsCSSCompressedDataBlock(0);
    nsCSSCompressedDataBlock *result = new(0) nsCSSCompressedDataBlock();
    result->SetBlockEnd(result->Block());
    return result;
    return result;
}
}


@@ -251,8 +311,12 @@ size_t
nsCSSCompressedDataBlock::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
nsCSSCompressedDataBlock::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
{
{
    size_t n = aMallocSizeOf(this);
    size_t n = aMallocSizeOf(this);
    for (PRUint32 i = 0; i < mNumProps; i++) {

        n += ValueAtIndex(i)->SizeOfExcludingThis(aMallocSizeOf);
    const char* cursor = Block();
    const char* cursor_end = BlockEnd();
    while (cursor < cursor_end) {
        n += ValueAtCursor(cursor)->SizeOfExcludingThis(aMallocSizeOf);
        cursor += CDBValueStorage_advance;
    }
    }
    return n;
    return n;
}
}
@@ -277,8 +341,10 @@ nsCSSExpandedDataBlock::DoExpand(nsCSSCompressedDataBlock *aBlock,
     * Save needless copying and allocation by copying the memory
     * Save needless copying and allocation by copying the memory
     * corresponding to the stored data in the compressed block.
     * corresponding to the stored data in the compressed block.
     */
     */
    for (PRUint32 i = 0; i < aBlock->mNumProps; i++) {
    const char* cursor = aBlock->Block();
        nsCSSProperty iProp = aBlock->PropertyAtIndex(i);
    const char* cursor_end = aBlock->BlockEnd();
    while (cursor < cursor_end) {
        nsCSSProperty iProp = PropertyAtCursor(cursor);
        NS_ABORT_IF_FALSE(!nsCSSProps::IsShorthand(iProp), "out of range");
        NS_ABORT_IF_FALSE(!nsCSSProps::IsShorthand(iProp), "out of range");
        NS_ABORT_IF_FALSE(!HasPropertyBit(iProp),
        NS_ABORT_IF_FALSE(!HasPropertyBit(iProp),
                          "compressed block has property multiple times");
                          "compressed block has property multiple times");
@@ -286,7 +352,7 @@ nsCSSExpandedDataBlock::DoExpand(nsCSSCompressedDataBlock *aBlock,
        if (aImportant)
        if (aImportant)
            SetImportantBit(iProp);
            SetImportantBit(iProp);


        const nsCSSValue* val = aBlock->ValueAtIndex(i);
        const nsCSSValue* val = ValueAtCursor(cursor);
        nsCSSValue* dest = PropertyAt(iProp);
        nsCSSValue* dest = PropertyAt(iProp);
        NS_ABORT_IF_FALSE(val->GetUnit() != eCSSUnit_Null, "oops");
        NS_ABORT_IF_FALSE(val->GetUnit() != eCSSUnit_Null, "oops");
        NS_ABORT_IF_FALSE(dest->GetUnit() == eCSSUnit_Null,
        NS_ABORT_IF_FALSE(dest->GetUnit() == eCSSUnit_Null,
@@ -295,11 +361,12 @@ nsCSSExpandedDataBlock::DoExpand(nsCSSCompressedDataBlock *aBlock,
        dest->~nsCSSValue();
        dest->~nsCSSValue();
#endif
#endif
        memcpy(dest, val, sizeof(nsCSSValue));
        memcpy(dest, val, sizeof(nsCSSValue));
        cursor += CDBValueStorage_advance;
    }
    }
    NS_ABORT_IF_FALSE(cursor == cursor_end, "inconsistent data");


    // Set the number of properties to zero so that we don't destroy the
    // Don't destroy remnants of what we just copied
    // remnants of what we just copied.
    aBlock->SetBlockEnd(aBlock->Block());
    aBlock->SetNumPropsToZero();
    delete aBlock;
    delete aBlock;
}
}


@@ -316,11 +383,10 @@ nsCSSExpandedDataBlock::Expand(nsCSSCompressedDataBlock *aNormalBlock,
    }
    }
}
}


void
nsCSSExpandedDataBlock::ComputeSizeResult
nsCSSExpandedDataBlock::ComputeNumProps(PRUint32* aNumPropsNormal,
nsCSSExpandedDataBlock::ComputeSize()
                                        PRUint32* aNumPropsImportant)
{
{
    *aNumPropsNormal = *aNumPropsImportant = 0;
    ComputeSizeResult result = {0, 0};
    for (size_t iHigh = 0; iHigh < nsCSSPropertySet::kChunkCount; ++iHigh) {
    for (size_t iHigh = 0; iHigh < nsCSSPropertySet::kChunkCount; ++iHigh) {
        if (!mPropertiesSet.HasPropertyInChunk(iHigh))
        if (!mPropertiesSet.HasPropertyInChunk(iHigh))
            continue;
            continue;
@@ -334,11 +400,12 @@ nsCSSExpandedDataBlock::ComputeNumProps(PRUint32* aNumPropsNormal,
            NS_ABORT_IF_FALSE(PropertyAt(iProp)->GetUnit() != eCSSUnit_Null,
            NS_ABORT_IF_FALSE(PropertyAt(iProp)->GetUnit() != eCSSUnit_Null,
                              "null value while computing size");
                              "null value while computing size");
            if (mPropertiesImportant.HasPropertyAt(iHigh, iLow))
            if (mPropertiesImportant.HasPropertyAt(iHigh, iLow))
                (*aNumPropsImportant)++;
                result.important += CDBValueStorage_advance;
            else
            else
                (*aNumPropsNormal)++;
                result.normal += CDBValueStorage_advance;
        }
        }
    }
    }
    return result;
}
}


void
void
@@ -346,19 +413,19 @@ nsCSSExpandedDataBlock::Compress(nsCSSCompressedDataBlock **aNormalBlock,
                                 nsCSSCompressedDataBlock **aImportantBlock)
                                 nsCSSCompressedDataBlock **aImportantBlock)
{
{
    nsAutoPtr<nsCSSCompressedDataBlock> result_normal, result_important;
    nsAutoPtr<nsCSSCompressedDataBlock> result_normal, result_important;
    PRUint32 i_normal = 0, i_important = 0;
    char *cursor_normal, *cursor_important;


    PRUint32 numPropsNormal, numPropsImportant;
    ComputeSizeResult size = ComputeSize();
    ComputeNumProps(&numPropsNormal, &numPropsImportant);


    result_normal =
    result_normal = new(size.normal) nsCSSCompressedDataBlock();
        new(numPropsNormal) nsCSSCompressedDataBlock(numPropsNormal);
    cursor_normal = result_normal->Block();


    if (numPropsImportant != 0) {
    if (size.important != 0) {
        result_important =
        result_important = new(size.important) nsCSSCompressedDataBlock();
            new(numPropsImportant) nsCSSCompressedDataBlock(numPropsImportant);
        cursor_important = result_important->Block();
    } else {
    } else {
        result_important = nsnull;
        result_important = nsnull;
        cursor_important = nsnull;
    }
    }


    /*
    /*
@@ -376,25 +443,32 @@ nsCSSExpandedDataBlock::Compress(nsCSSCompressedDataBlock **aNormalBlock,
            NS_ABORT_IF_FALSE(!nsCSSProps::IsShorthand(iProp), "out of range");
            NS_ABORT_IF_FALSE(!nsCSSProps::IsShorthand(iProp), "out of range");
            bool important =
            bool important =
                mPropertiesImportant.HasPropertyAt(iHigh, iLow);
                mPropertiesImportant.HasPropertyAt(iHigh, iLow);
            char *&cursor = important ? cursor_important : cursor_normal;
            nsCSSCompressedDataBlock *result =
            nsCSSCompressedDataBlock *result =
                important ? result_important : result_normal;
                important ? result_important : result_normal;
            PRUint32* ip = important ? &i_important : &i_normal;
            nsCSSValue* val = PropertyAt(iProp);
            nsCSSValue* val = PropertyAt(iProp);
            NS_ABORT_IF_FALSE(val->GetUnit() != eCSSUnit_Null,
            NS_ABORT_IF_FALSE(val->GetUnit() != eCSSUnit_Null,
                              "Null value while compressing");
                              "Null value while compressing");
            result->SetPropertyAtIndex(*ip, iProp);
            CDBValueStorage *storage =
            result->RawCopyValueToIndex(*ip, val);
                reinterpret_cast<CDBValueStorage*>(cursor);
            storage->property = iProp;
            memcpy(&storage->value, val, sizeof(nsCSSValue));
            new (val) nsCSSValue();
            new (val) nsCSSValue();
            (*ip)++;
            cursor += CDBValueStorage_advance;
            result->mStyleBits |=
            result->mStyleBits |=
                nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[iProp]);
                nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[iProp]);
        }
        }
    }
    }


    NS_ABORT_IF_FALSE(numPropsNormal == i_normal, "bad numProps");
    result_normal->SetBlockEnd(cursor_normal);
    NS_ABORT_IF_FALSE(result_normal->DataSize() == ptrdiff_t(size.normal),
                      "size miscalculation");


    if (result_important) {
    if (result_important) {
        NS_ABORT_IF_FALSE(numPropsImportant == i_important, "bad numProps");
        result_important->SetBlockEnd(cursor_important);
        NS_ABORT_IF_FALSE(result_important->DataSize() ==
                          ptrdiff_t(size.important),
                          "size miscalculation");
    }
    }


    ClearSets();
    ClearSets();
+45 −76
Original line number Original line Diff line number Diff line
@@ -55,6 +55,16 @@ class Declaration;
}
}
}
}


/*
 * nsCSSCompressedDataBlock holds property-value pairs corresponding
 * to CSS declaration blocks.  Each pair is stored in a CDBValueStorage
 * object; these objects form an array at the end of the data block.
 */
struct CDBValueStorage {
    nsCSSProperty property;
    nsCSSValue value;
};

/**
/**
 * An |nsCSSCompressedDataBlock| holds a usually-immutable chunk of
 * An |nsCSSCompressedDataBlock| holds a usually-immutable chunk of
 * property-value data for a CSS declaration block (which we misname a
 * property-value data for a CSS declaration block (which we misname a
@@ -67,9 +77,7 @@ private:


    // Only this class (via |CreateEmptyBlock|) or nsCSSExpandedDataBlock
    // Only this class (via |CreateEmptyBlock|) or nsCSSExpandedDataBlock
    // (in |Compress|) can create compressed data blocks.
    // (in |Compress|) can create compressed data blocks.
    nsCSSCompressedDataBlock(PRUint32 aNumProps)
    nsCSSCompressedDataBlock() : mStyleBits(0) {}
      : mStyleBits(0), mNumProps(aNumProps)
    {}


public:
public:
    ~nsCSSCompressedDataBlock();
    ~nsCSSCompressedDataBlock();
@@ -116,88 +124,47 @@ public:
    size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
    size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;


private:
private:
    void* operator new(size_t aBaseSize, PRUint32 aNumProps) {
    void* operator new(size_t aBaseSize, size_t aDataSize) {
        NS_ABORT_IF_FALSE(aBaseSize == sizeof(nsCSSCompressedDataBlock),
        NS_ABORT_IF_FALSE(aBaseSize == sizeof(nsCSSCompressedDataBlock),
                          "unexpected size for nsCSSCompressedDataBlock");
                          "unexpected size for nsCSSCompressedDataBlock");
        return ::operator new(aBaseSize + DataSize(aNumProps));
        return ::operator new(aBaseSize + aDataSize);
    }
    }


public:
    /**
    // Ideally, |nsCSSProperty| would be |enum nsCSSProperty : PRInt16|.  But
     * Delete all the data stored in this block, and the block itself.
    // not all of the compilers we use are modern enough to support small
     */
    // enums.  So we manually squeeze nsCSSProperty into 16 bits ourselves.
    void Destroy();
    // The static assertion below ensures it fits.
    typedef PRInt16 CompressedCSSProperty;
    static const size_t MaxCompressedCSSProperty = PR_INT16_MAX;

private:
    static size_t DataSize(PRUint32 aNumProps) {
        return size_t(aNumProps) *
               (sizeof(nsCSSValue) + sizeof(CompressedCSSProperty));
    }


    PRInt32 mStyleBits; // the structs for which we have data, according to
    PRInt32 mStyleBits; // the structs for which we have data, according to
                        // |nsCachedStyleData::GetBitForSID|.
                        // |nsCachedStyleData::GetBitForSID|.
    PRUint32 mNumProps;
    PRUint32 mDataSize;
    // nsCSSValue elements are stored after these fields, and
    // CDBValueStorage elements are stored after these fields.  Space for them
    // nsCSSProperty elements are stored -- each one compressed as a
    // CompressedCSSProperty -- after the nsCSSValue elements.  Space for them
    // is allocated in |operator new| above.  The static assertions following
    // is allocated in |operator new| above.  The static assertions following
    // this class make sure that the value and property elements are aligned
    // this class make sure that the CDBValueStorage elements are aligned
    // appropriately.
    // appropriately.
    
    
    nsCSSValue* Values() const {
    char* Block() { return (char*)this + sizeof(*this); }
        return (nsCSSValue*)(this + 1);
    char* BlockEnd() { return Block() + mDataSize; }
    }
    const char* Block() const { return (char*)this + sizeof(*this); }

    const char* BlockEnd() const { return Block() + mDataSize; }
    CompressedCSSProperty* CompressedProperties() const {
    void SetBlockEnd(char *blockEnd) { 
        return (CompressedCSSProperty*)(Values() + mNumProps);
        /*
    }
         * Note:  if we ever change nsCSSDeclaration to store the declarations

         * in order and also store repeated declarations of the same property,
    nsCSSValue* ValueAtIndex(PRUint32 i) const {
         * then we need to worry about checking for integer overflow here.
        NS_ABORT_IF_FALSE(i < mNumProps, "value index out of range");
         */
        return Values() + i;
        NS_ABORT_IF_FALSE(size_t(blockEnd - Block()) <= size_t(PR_UINT32_MAX),
    }
                          "overflow of mDataSize");

        mDataSize = PRUint32(blockEnd - Block());
    nsCSSProperty PropertyAtIndex(PRUint32 i) const {
        NS_ABORT_IF_FALSE(i < mNumProps, "property index out of range");
        nsCSSProperty prop = (nsCSSProperty)CompressedProperties()[i];
        NS_ABORT_IF_FALSE(!nsCSSProps::IsShorthand(prop), "out of range");
        return prop;
    }

    void CopyValueToIndex(PRUint32 i, nsCSSValue* aValue) {
        new (ValueAtIndex(i)) nsCSSValue(*aValue);
    }

    void RawCopyValueToIndex(PRUint32 i, nsCSSValue* aValue) {
        memcpy(ValueAtIndex(i), aValue, sizeof(nsCSSValue));
    }

    void SetPropertyAtIndex(PRUint32 i, nsCSSProperty aProperty) {
        NS_ABORT_IF_FALSE(i < mNumProps, "set property index out of range");
        CompressedProperties()[i] = (CompressedCSSProperty)aProperty;
    }

    void SetNumPropsToZero() {
        mNumProps = 0;
    }
    }
    ptrdiff_t DataSize() const { return mDataSize; }
};
};


// Make sure the values and properties are aligned appropriately.  (These
/* Make sure the CDBValueStorage elements are aligned appropriately. */
// assertions are stronger than necessary to keep them simple.)
MOZ_STATIC_ASSERT(sizeof(nsCSSCompressedDataBlock) == 8,
MOZ_STATIC_ASSERT(sizeof(nsCSSCompressedDataBlock) == 8,
                  "nsCSSCompressedDataBlock's size has changed");
                  "nsCSSCompressedDataBlock's size has changed");
MOZ_STATIC_ASSERT(NS_ALIGNMENT_OF(nsCSSValue) == 4 ||
MOZ_STATIC_ASSERT(NS_ALIGNMENT_OF(CDBValueStorage) <= 8,
                  NS_ALIGNMENT_OF(nsCSSValue) == 8,
                  "CDBValueStorage needs too much alignment");
                  "nsCSSValue doesn't align with nsCSSCompressedDataBlock"); 
MOZ_STATIC_ASSERT(NS_ALIGNMENT_OF(nsCSSCompressedDataBlock::CompressedCSSProperty) == 2,
                  "CompressedCSSProperty doesn't align with nsCSSValue"); 

// Make sure that sizeof(CompressedCSSProperty) is big enough.
MOZ_STATIC_ASSERT(eCSSProperty_COUNT_no_shorthands <=
                  nsCSSCompressedDataBlock::MaxCompressedCSSProperty,
                  "nsCSSProperty doesn't fit in StoredSizeOfCSSProperty");


class nsCSSExpandedDataBlock {
class nsCSSExpandedDataBlock {
    friend class nsCSSCompressedDataBlock;
    friend class nsCSSCompressedDataBlock;
@@ -284,11 +251,13 @@ public:


private:
private:
    /**
    /**
     * Compute the number of properties that will be present in the
     * Compute the size that will be occupied by the result of
     * result of |Compress|.
     * |Compress|.
     */
     */
    void ComputeNumProps(PRUint32* aNumPropsNormal,
    struct ComputeSizeResult {
                         PRUint32* aNumPropsImportant);
        PRUint32 normal, important;
    };
    ComputeSizeResult ComputeSize();


    void DoExpand(nsCSSCompressedDataBlock *aBlock, bool aImportant);
    void DoExpand(nsCSSCompressedDataBlock *aBlock, bool aImportant);