Instead of stack-allocating nsRuleData* structs in separate methods for each style struct, allocate an array of nsCSSValue using alloca. (Bug 636039, patch 15) r=bzbarsky

This commit is contained in:
L. David Baron 2011-03-17 20:14:31 -07:00
parent aa39d3bc8d
commit 8f037974d7
5 changed files with 303 additions and 555 deletions

View File

@ -2085,6 +2085,8 @@ nsCSSProps::kSubpropertyTable[eCSSProperty_COUNT - eCSSProperty_COUNT_no_shortha
stylestructoffset_, animtype_) \
ePropertyIndex_for_##id_,
// The order of these enums must match the g*Flags arrays in nsRuleNode.cpp.
enum FontCheckCounter {
#define CSS_PROP_FONT ENUM_DATA_FOR_PROPERTY
#include "nsCSSPropList.h"

View File

@ -38,45 +38,3 @@
#include "nsRuleData.h"
#include "nsCSSProps.h"
namespace {
struct PropertyOffsetInfo {
// XXX These could probably be pointer-to-member, if the casting can
// be done correctly.
size_t struct_offset; // offset of nsRuleDataThing* in nsRuleData
size_t member_offset; // offset of value in nsRuleDataThing
};
const PropertyOffsetInfo kOffsetTable[eCSSProperty_COUNT_no_shorthands] = {
#define CSS_PROP_BACKENDONLY(name_, id_, method_, flags_, datastruct_, \
member_, parsevariant_, kwtable_) \
{ size_t(-1), size_t(-1) },
#define CSS_PROP(name_, id_, method_, flags_, datastruct_, member_, \
parsevariant_, kwtable_, stylestruct_, stylestructoffset_,\
animtype_) \
{ offsetof(nsRuleData, m##datastruct_##Data), \
offsetof(nsRuleData##datastruct_, member_) },
#include "nsCSSPropList.h"
#undef CSS_PROP
#undef CSS_PROP_BACKENDONLY
};
} // anon namespace
nsCSSValue*
nsRuleData::ValueFor(nsCSSProperty aProperty)
{
NS_ABORT_IF_FALSE(aProperty < eCSSProperty_COUNT_no_shorthands,
"invalid or shorthand property");
const PropertyOffsetInfo& offsets = kOffsetTable[aProperty];
NS_ABORT_IF_FALSE(offsets.struct_offset != size_t(-1),
"backend-only property");
char* cssstruct = *reinterpret_cast<char**>
(reinterpret_cast<char*>(this) + offsets.struct_offset);
NS_ABORT_IF_FALSE(cssstruct, "substructure pointer should never be null");
return reinterpret_cast<nsCSSValue*>(cssstruct + offsets.member_offset);
}

View File

@ -64,20 +64,19 @@ struct nsRuleData
nsStyleContext* mStyleContext;
nsPostResolveFunc mPostResolveCallback;
// Should always be stack-allocated! We don't own these structures!
nsRuleDataFont* mFontData;
nsRuleDataDisplay* mDisplayData;
nsRuleDataMargin* mMarginData;
nsRuleDataList* mListData;
nsRuleDataPosition* mPositionData;
nsRuleDataTable* mTableData;
nsRuleDataColor* mColorData;
nsRuleDataContent* mContentData;
nsRuleDataText* mTextData;
nsRuleDataUserInterface* mUserInterfaceData;
nsRuleDataXUL* mXULData;
nsRuleDataSVG* mSVGData;
nsRuleDataColumn* mColumnData;
// We store nsCSSValues needed to compute the data for one or more
// style structs (specified by the bitfield mSIDs). These are stored
// in a single array allocation (which our caller allocates; see
// AutoCSSValueArray) The offset of each property |prop| in
// mValueStorage is the sum of
// mValueOffsets[nsCSSProps::kSIDTable[prop]] and
// nsCSSProps::PropertyIndexInStruct(prop). The only place we gather
// more than one style struct's data at a time is
// nsRuleNode::HasAuthorSpecifiedRules; therefore some code that we
// know is not called from HasAuthorSpecifiedRules assumes that the
// mValueOffsets for the one struct in mSIDs is zero.
nsCSSValue* mValueStorage; // our user owns this array
size_t mValueOffsets[nsStyleStructID_Length];
nsRuleData(PRUint32 aSIDs,
nsPresContext* aContext,
@ -86,22 +85,15 @@ struct nsRuleData
mCanStoreInRuleTree(PR_TRUE),
mPresContext(aContext),
mStyleContext(aStyleContext),
mPostResolveCallback(nsnull),
mFontData(nsnull),
mDisplayData(nsnull),
mMarginData(nsnull),
mListData(nsnull),
mPositionData(nsnull),
mTableData(nsnull),
mColorData(nsnull),
mContentData(nsnull),
mTextData(nsnull),
mUserInterfaceData(nsnull),
mXULData(nsnull),
mSVGData(nsnull),
mColumnData(nsnull)
{}
~nsRuleData() {}
mPostResolveCallback(nsnull)
{
// FIXME: fill with poison value?
}
~nsRuleData() {
#ifdef DEBUG
// FIXME: assert nothing in mSIDs has poison value
#endif
}
/**
* Return a pointer to the value object within |this| corresponding
@ -110,7 +102,24 @@ struct nsRuleData
* This function must only be called if the given property is in
* mSIDs.
*/
nsCSSValue* ValueFor(nsCSSProperty aProperty);
nsCSSValue* ValueFor(nsCSSProperty aProperty)
{
NS_ABORT_IF_FALSE(aProperty < eCSSProperty_COUNT_no_shorthands,
"invalid or shorthand property");
nsStyleStructID sid = nsCSSProps::kSIDTable[aProperty];
size_t indexInStruct = nsCSSProps::PropertyIndexInStruct(aProperty);
// This should really be nsCachedStyleData::GetBitForSID, but we can't
// include that here since it includes us.
NS_ABORT_IF_FALSE(mSIDs & (1 << sid),
"calling nsRuleData::ValueFor on property not in mSIDs");
NS_ABORT_IF_FALSE(sid != eStyleStruct_BackendOnly &&
indexInStruct != size_t(-1),
"backend-only property");
return mValueStorage + mValueOffsets[sid] + indexInStruct;
}
const nsCSSValue* ValueFor(nsCSSProperty aProperty) const {
return const_cast<nsRuleData*>(this)->ValueFor(aProperty);
@ -133,19 +142,16 @@ struct nsRuleData
NS_ABORT_IF_FALSE(mSIDs & NS_STYLE_INHERIT_BIT(stylestruct_), \
"Calling nsRuleData::ValueFor" #method_ " without " \
"NS_STYLE_INHERIT_BIT(" #stylestruct_ " in mSIDs."); \
nsRuleData##datastruct_ *cssstruct = m##datastruct_##Data; \
NS_ABORT_IF_FALSE(cssstruct, "nsRuleNode::Get" #stylestruct_ "Data " \
"set up nsRuleData incorrectly"); \
return &cssstruct->member_; \
nsStyleStructID sid = eStyleStruct_##stylestruct_; \
size_t indexInStruct = \
nsCSSProps::PropertyIndexInStruct(eCSSProperty_##id_); \
NS_ABORT_IF_FALSE(sid != eStyleStruct_BackendOnly && \
indexInStruct != size_t(-1), \
"backend-only property"); \
return mValueStorage + mValueOffsets[sid] + indexInStruct; \
} \
const nsCSSValue* ValueFor##method_() const { \
NS_ABORT_IF_FALSE(mSIDs & NS_STYLE_INHERIT_BIT(stylestruct_), \
"Calling nsRuleData::ValueFor" #method_ " without " \
"NS_STYLE_INHERIT_BIT(" #stylestruct_ " in mSIDs."); \
const nsRuleData##datastruct_ *cssstruct = m##datastruct_##Data; \
NS_ABORT_IF_FALSE(cssstruct, "nsRuleNode::Get" #stylestruct_ "Data " \
"set up nsRuleData incorrectly"); \
return &cssstruct->member_; \
return const_cast<nsRuleData*>(this)->ValueFor##method_(); \
}
#define CSS_PROP_BACKENDONLY(name_, id_, method_, flags_, datastruct_, \
member_, parsevariant_, kwtable_) \

File diff suppressed because it is too large Load Diff

View File

@ -55,8 +55,6 @@ struct nsRuleData;
class nsIStyleRule;
struct nsCSSStruct;
struct nsCSSValueList;
// Copy of typedef that's in nsCSSStruct.h, for compilation speed.
typedef nsCSSStruct nsRuleDataStruct;
class nsCSSValue;
struct nsCSSRect;
@ -458,8 +456,7 @@ protected:
nsStyleContext* aContext);
const void*
WalkRuleTree(const nsStyleStructID aSID, nsStyleContext* aContext,
nsRuleData* aRuleData, nsRuleDataStruct* aSpecificData);
WalkRuleTree(const nsStyleStructID aSID, nsStyleContext* aContext);
const void*
ComputeDisplayData(void* aStartStruct,
@ -661,7 +658,8 @@ protected:
nsCSSRect& aValueRect,
PRBool& aCanStoreInRuleTree);
inline RuleDetail CheckSpecifiedProperties(const nsStyleStructID aSID, const nsRuleDataStruct& aRuleDataStruct);
inline RuleDetail CheckSpecifiedProperties(const nsStyleStructID aSID,
const nsRuleData* aRuleData);
const void* GetParentData(const nsStyleStructID aSID);
#define STYLE_STRUCT(name_, checkdata_cb_, ctor_args_) \
@ -669,32 +667,6 @@ protected:
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
const void* GetDisplayData(nsStyleContext* aContext);
const void* GetVisibilityData(nsStyleContext* aContext);
const void* GetFontData(nsStyleContext* aContext);
const void* GetColorData(nsStyleContext* aContext);
const void* GetBackgroundData(nsStyleContext* aContext);
const void* GetMarginData(nsStyleContext* aContext);
const void* GetBorderData(nsStyleContext* aContext);
const void* GetPaddingData(nsStyleContext* aContext);
const void* GetOutlineData(nsStyleContext* aContext);
const void* GetListData(nsStyleContext* aContext);
const void* GetPositionData(nsStyleContext* aContext);
const void* GetTableData(nsStyleContext* aContext);
const void* GetTableBorderData(nsStyleContext* aContext);
const void* GetContentData(nsStyleContext* aContext);
const void* GetQuotesData(nsStyleContext* aContext);
const void* GetTextData(nsStyleContext* aContext);
const void* GetTextResetData(nsStyleContext* aContext);
const void* GetUserInterfaceData(nsStyleContext* aContext);
const void* GetUIResetData(nsStyleContext* aContext);
const void* GetXULData(nsStyleContext* aContext);
const void* GetColumnData(nsStyleContext* aContext);
const void* GetSVGData(nsStyleContext* aContext);
const void* GetSVGResetData(nsStyleContext* aContext);
already_AddRefed<nsCSSShadowArray>
GetShadowData(const nsCSSValueList* aList,
nsStyleContext* aContext,