mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Make nsCachedStyleData store arrays of nsStyleStruct*, and use style struct IDs for faster access to those arrays. (Bug 639231, patch 3) r=bzbarsky
This commit is contained in:
parent
52152cb738
commit
8ff298d446
@ -2294,9 +2294,11 @@ nsRuleNode::AdjustLogicalBoxProp(nsStyleContext* aContext,
|
||||
return nsnull; \
|
||||
} \
|
||||
} \
|
||||
NS_ASSERTION(!aHighestNode->mStyleData.mInheritedData->m##type_##Data, \
|
||||
NS_ASSERTION(!aHighestNode->mStyleData.mInheritedData-> \
|
||||
mStyleStructs[eStyleStruct_##type_], \
|
||||
"Going to leak style data"); \
|
||||
aHighestNode->mStyleData.mInheritedData->m##type_##Data = data_; \
|
||||
aHighestNode->mStyleData.mInheritedData-> \
|
||||
mStyleStructs[eStyleStruct_##type_] = data_; \
|
||||
/* Propagate the bit down. */ \
|
||||
PropagateDependentBit(NS_STYLE_INHERIT_BIT(type_), aHighestNode); \
|
||||
/* Tell the style context that it doesn't own the data */ \
|
||||
@ -2336,9 +2338,11 @@ nsRuleNode::AdjustLogicalBoxProp(nsStyleContext* aContext,
|
||||
return nsnull; \
|
||||
} \
|
||||
} \
|
||||
NS_ASSERTION(!aHighestNode->mStyleData.mResetData->m##type_##Data, \
|
||||
NS_ASSERTION(!aHighestNode->mStyleData.mResetData-> \
|
||||
mStyleStructs[eStyleStruct_##type_], \
|
||||
"Going to leak style data"); \
|
||||
aHighestNode->mStyleData.mResetData->m##type_##Data = data_; \
|
||||
aHighestNode->mStyleData.mResetData-> \
|
||||
mStyleStructs[eStyleStruct_##type_] = data_; \
|
||||
/* Propagate the bit down. */ \
|
||||
PropagateDependentBit(NS_STYLE_INHERIT_BIT(type_), aHighestNode); \
|
||||
} \
|
||||
|
@ -61,17 +61,29 @@ struct nsCSSRect;
|
||||
|
||||
class nsStyleCoord;
|
||||
|
||||
template <nsStyleStructID MinIndex, nsStyleStructID Count>
|
||||
class FixedStyleStructArray
|
||||
{
|
||||
private:
|
||||
void* mArray[Count];
|
||||
public:
|
||||
void*& operator[](nsStyleStructID aIndex) {
|
||||
NS_ABORT_IF_FALSE(MinIndex <= aIndex && aIndex < (MinIndex + Count),
|
||||
"out of range");
|
||||
return mArray[aIndex - MinIndex];
|
||||
}
|
||||
|
||||
const void* operator[](nsStyleStructID aIndex) const {
|
||||
NS_ABORT_IF_FALSE(MinIndex <= aIndex && aIndex < (MinIndex + Count),
|
||||
"out of range");
|
||||
return mArray[aIndex - MinIndex];
|
||||
}
|
||||
};
|
||||
|
||||
struct nsInheritedStyleData
|
||||
{
|
||||
|
||||
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
|
||||
nsStyle##name * m##name##Data;
|
||||
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args)
|
||||
|
||||
#include "nsStyleStructList.h"
|
||||
|
||||
#undef STYLE_STRUCT_INHERITED
|
||||
#undef STYLE_STRUCT_RESET
|
||||
FixedStyleStructArray<nsStyleStructID_Inherited_Start,
|
||||
nsStyleStructID_Inherited_Count> mStyleStructs;
|
||||
|
||||
void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
|
||||
return aContext->AllocateFromShell(sz);
|
||||
@ -79,8 +91,9 @@ struct nsInheritedStyleData
|
||||
|
||||
void DestroyStructs(PRUint32 aBits, nsPresContext* aContext) {
|
||||
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
|
||||
if (m##name##Data && !(aBits & NS_STYLE_INHERIT_BIT(name))) \
|
||||
m##name##Data->Destroy(aContext);
|
||||
void *name##Data = mStyleStructs[eStyleStruct_##name]; \
|
||||
if (name##Data && !(aBits & NS_STYLE_INHERIT_BIT(name))) \
|
||||
static_cast<nsStyle##name*>(name##Data)->Destroy(aContext);
|
||||
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args)
|
||||
|
||||
#include "nsStyleStructList.h"
|
||||
@ -95,30 +108,26 @@ struct nsInheritedStyleData
|
||||
}
|
||||
|
||||
nsInheritedStyleData() {
|
||||
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
|
||||
m##name##Data = nsnull;
|
||||
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args)
|
||||
|
||||
#include "nsStyleStructList.h"
|
||||
|
||||
#undef STYLE_STRUCT_INHERITED
|
||||
#undef STYLE_STRUCT_RESET
|
||||
|
||||
for (nsStyleStructID i = nsStyleStructID_Inherited_Start;
|
||||
i < nsStyleStructID_Inherited_Start + nsStyleStructID_Inherited_Count;
|
||||
i = nsStyleStructID(i + 1)) {
|
||||
mStyleStructs[i] = nsnull;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct nsResetStyleData
|
||||
{
|
||||
FixedStyleStructArray<nsStyleStructID_Reset_Start,
|
||||
nsStyleStructID_Reset_Count> mStyleStructs;
|
||||
|
||||
nsResetStyleData()
|
||||
{
|
||||
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
|
||||
m##name##Data = nsnull;
|
||||
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args)
|
||||
|
||||
#include "nsStyleStructList.h"
|
||||
|
||||
#undef STYLE_STRUCT_RESET
|
||||
#undef STYLE_STRUCT_INHERITED
|
||||
for (nsStyleStructID i = nsStyleStructID_Reset_Start;
|
||||
i < nsStyleStructID_Reset_Start + nsStyleStructID_Reset_Count;
|
||||
i = nsStyleStructID(i + 1)) {
|
||||
mStyleStructs[i] = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
|
||||
@ -127,8 +136,9 @@ struct nsResetStyleData
|
||||
|
||||
void Destroy(PRUint32 aBits, nsPresContext* aContext) {
|
||||
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
|
||||
if (m##name##Data && !(aBits & NS_STYLE_INHERIT_BIT(name))) \
|
||||
m##name##Data->Destroy(aContext);
|
||||
void *name##Data = mStyleStructs[eStyleStruct_##name]; \
|
||||
if (name##Data && !(aBits & NS_STYLE_INHERIT_BIT(name))) \
|
||||
static_cast<nsStyle##name*>(name##Data)->Destroy(aContext);
|
||||
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args)
|
||||
|
||||
#include "nsStyleStructList.h"
|
||||
@ -138,78 +148,46 @@ struct nsResetStyleData
|
||||
|
||||
aContext->FreeToShell(sizeof(nsResetStyleData), this);
|
||||
}
|
||||
|
||||
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
|
||||
nsStyle##name * m##name##Data;
|
||||
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args)
|
||||
|
||||
#include "nsStyleStructList.h"
|
||||
|
||||
#undef STYLE_STRUCT_RESET
|
||||
#undef STYLE_STRUCT_INHERITED
|
||||
|
||||
};
|
||||
|
||||
struct nsCachedStyleData
|
||||
{
|
||||
struct StyleStructInfo {
|
||||
ptrdiff_t mCachedStyleDataOffset;
|
||||
ptrdiff_t mInheritResetOffset;
|
||||
PRBool mIsReset;
|
||||
};
|
||||
|
||||
static StyleStructInfo gInfo[];
|
||||
|
||||
nsInheritedStyleData* mInheritedData;
|
||||
nsResetStyleData* mResetData;
|
||||
|
||||
static PRBool IsReset(const nsStyleStructID& aSID) {
|
||||
return gInfo[aSID].mIsReset;
|
||||
static PRBool IsReset(const nsStyleStructID aSID) {
|
||||
NS_ABORT_IF_FALSE(0 <= aSID && aSID < nsStyleStructID_Length,
|
||||
"must be an inherited or reset SID");
|
||||
return nsStyleStructID_Reset_Start <= aSID;
|
||||
}
|
||||
|
||||
static PRUint32 GetBitForSID(const nsStyleStructID& aSID) {
|
||||
static PRUint32 GetBitForSID(const nsStyleStructID aSID) {
|
||||
return 1 << aSID;
|
||||
}
|
||||
|
||||
void* NS_FASTCALL GetStyleData(const nsStyleStructID& aSID) {
|
||||
// Each struct is stored at this.m##type##Data->m##name##Data where
|
||||
// |type| is either Inherit or Reset, and |name| is the name of the
|
||||
// style struct. The |gInfo| stores the offset of the appropriate
|
||||
// m##type##Data for the struct within nsCachedStyleData (|this|)
|
||||
// and the offset of the appropriate m##name##Data within the
|
||||
// m##type##Data. Note that if we don't have any reset structs,
|
||||
// then mResetData is null, and likewise for mInheritedData. This
|
||||
// saves us from having to go through the long if-else cascade into
|
||||
// which most compilers will turn a case statement.
|
||||
|
||||
// NOTE: nsStyleContext::SetStyle works roughly the same way.
|
||||
|
||||
const StyleStructInfo& info = gInfo[aSID];
|
||||
|
||||
// Get either &mInheritedData or &mResetData.
|
||||
char* resetOrInheritSlot = reinterpret_cast<char*>(this) + info.mCachedStyleDataOffset;
|
||||
|
||||
// Get either mInheritedData or mResetData.
|
||||
char* resetOrInherit = reinterpret_cast<char*>(*reinterpret_cast<void**>(resetOrInheritSlot));
|
||||
|
||||
void* data = nsnull;
|
||||
if (resetOrInherit) {
|
||||
// If we have the mInheritedData or mResetData, then we might have
|
||||
// the struct, so get it.
|
||||
char* dataSlot = resetOrInherit + info.mInheritResetOffset;
|
||||
data = *reinterpret_cast<void**>(dataSlot);
|
||||
void* NS_FASTCALL GetStyleData(const nsStyleStructID aSID) {
|
||||
if (IsReset(aSID)) {
|
||||
if (mResetData) {
|
||||
return mResetData->mStyleStructs[aSID];
|
||||
}
|
||||
} else {
|
||||
if (mInheritedData) {
|
||||
return mInheritedData->mStyleStructs[aSID];
|
||||
}
|
||||
}
|
||||
return data;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Typesafe and faster versions of the above
|
||||
#define STYLE_STRUCT_INHERITED(name_, checkdata_cb_, ctor_args_) \
|
||||
nsStyle##name_ * NS_FASTCALL GetStyle##name_ () { \
|
||||
return mInheritedData ? mInheritedData->m##name_##Data : nsnull; \
|
||||
nsStyle##name_ * NS_FASTCALL GetStyle##name_ () { \
|
||||
return mInheritedData ? static_cast<nsStyle##name_*>( \
|
||||
mInheritedData->mStyleStructs[eStyleStruct_##name_]) : nsnull; \
|
||||
}
|
||||
#define STYLE_STRUCT_RESET(name_, checkdata_cb_, ctor_args_) \
|
||||
nsStyle##name_ * NS_FASTCALL GetStyle##name_ () { \
|
||||
return mResetData ? mResetData->m##name_##Data : nsnull; \
|
||||
nsStyle##name_ * NS_FASTCALL GetStyle##name_ () { \
|
||||
return mResetData ? static_cast<nsStyle##name_*>( \
|
||||
mResetData->mStyleStructs[eStyleStruct_##name_]) : nsnull; \
|
||||
}
|
||||
#include "nsStyleStructList.h"
|
||||
#undef STYLE_STRUCT_RESET
|
||||
|
@ -226,19 +226,14 @@ nsStyleContext::FindChildWithRules(const nsIAtom* aPseudoTag,
|
||||
const void* nsStyleContext::GetCachedStyleData(nsStyleStructID aSID)
|
||||
{
|
||||
const void* cachedData;
|
||||
PRBool isReset = nsCachedStyleData::IsReset(aSID);
|
||||
if (isReset) {
|
||||
if (nsCachedStyleData::IsReset(aSID)) {
|
||||
if (mCachedResetData) {
|
||||
char* slot = reinterpret_cast<char*>(mCachedResetData) +
|
||||
nsCachedStyleData::gInfo[aSID].mInheritResetOffset;
|
||||
cachedData = *reinterpret_cast<void**>(slot);
|
||||
cachedData = mCachedResetData->mStyleStructs[aSID];
|
||||
} else {
|
||||
cachedData = nsnull;
|
||||
}
|
||||
} else {
|
||||
char* slot = reinterpret_cast<char*>(&mCachedInheritedData) +
|
||||
nsCachedStyleData::gInfo[aSID].mInheritResetOffset;
|
||||
cachedData = *reinterpret_cast<void**>(slot);
|
||||
cachedData = mCachedInheritedData.mStyleStructs[aSID];
|
||||
}
|
||||
return cachedData;
|
||||
}
|
||||
@ -314,22 +309,19 @@ nsStyleContext::SetStyle(nsStyleStructID aSID, void* aStruct)
|
||||
// See the comments there (in nsRuleNode.h) for more details about
|
||||
// what this is doing and why.
|
||||
|
||||
char* dataSlot;
|
||||
void** dataSlot;
|
||||
if (nsCachedStyleData::IsReset(aSID)) {
|
||||
if (!mCachedResetData) {
|
||||
mCachedResetData = new (mRuleNode->GetPresContext()) nsResetStyleData;
|
||||
// XXXbz And if that fails?
|
||||
}
|
||||
dataSlot = reinterpret_cast<char*>(mCachedResetData) +
|
||||
nsCachedStyleData::gInfo[aSID].mInheritResetOffset;
|
||||
dataSlot = &mCachedResetData->mStyleStructs[aSID];
|
||||
} else {
|
||||
dataSlot = reinterpret_cast<char*>(&mCachedInheritedData) +
|
||||
nsCachedStyleData::gInfo[aSID].mInheritResetOffset;
|
||||
dataSlot = &mCachedInheritedData.mStyleStructs[aSID];
|
||||
}
|
||||
NS_ASSERTION(!*reinterpret_cast<void**>(dataSlot) ||
|
||||
(mBits & nsCachedStyleData::GetBitForSID(aSID)),
|
||||
NS_ASSERTION(!*dataSlot || (mBits & nsCachedStyleData::GetBitForSID(aSID)),
|
||||
"Going to leak style data");
|
||||
*reinterpret_cast<void**>(dataSlot) = aStruct;
|
||||
*dataSlot = aStruct;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -208,11 +208,13 @@ public:
|
||||
// Setters for inherit structs only, since rulenode only sets those eagerly.
|
||||
#define STYLE_STRUCT_INHERITED(name_, checkdata_cb_, ctor_args_) \
|
||||
void SetStyle##name_ (nsStyle##name_ * aStruct) { \
|
||||
NS_ASSERTION(!mCachedInheritedData.m##name_##Data || \
|
||||
void *& slot = \
|
||||
mCachedInheritedData.mStyleStructs[eStyleStruct_##name_]; \
|
||||
NS_ASSERTION(!slot || \
|
||||
(mBits & \
|
||||
nsCachedStyleData::GetBitForSID(eStyleStruct_##name_)), \
|
||||
"Going to leak styledata"); \
|
||||
mCachedInheritedData.m##name_##Data = aStruct; \
|
||||
slot = aStruct; \
|
||||
}
|
||||
#define STYLE_STRUCT_RESET(name_, checkdata_cb_, ctor_args_) /* nothing */
|
||||
#include "nsStyleStructList.h"
|
||||
@ -350,7 +352,8 @@ protected:
|
||||
#define STYLE_STRUCT_INHERITED(name_, checkdata_cb_, ctor_args_) \
|
||||
const nsStyle##name_ * DoGetStyle##name_(PRBool aComputeData) { \
|
||||
const nsStyle##name_ * cachedData = \
|
||||
mCachedInheritedData.m##name_##Data; \
|
||||
static_cast<nsStyle##name_*>( \
|
||||
mCachedInheritedData.mStyleStructs[eStyleStruct_##name_]); \
|
||||
if (cachedData) /* Have it cached already, yay */ \
|
||||
return cachedData; \
|
||||
/* Have the rulenode deal */ \
|
||||
@ -358,8 +361,10 @@ protected:
|
||||
}
|
||||
#define STYLE_STRUCT_RESET(name_, checkdata_cb_, ctor_args_) \
|
||||
const nsStyle##name_ * DoGetStyle##name_(PRBool aComputeData) { \
|
||||
const nsStyle##name_ * cachedData = \
|
||||
mCachedResetData ? mCachedResetData->m##name_##Data : nsnull; \
|
||||
const nsStyle##name_ * cachedData = mCachedResetData \
|
||||
? static_cast<nsStyle##name_*>( \
|
||||
mCachedResetData->mStyleStructs[eStyleStruct_##name_]) \
|
||||
: nsnull; \
|
||||
if (cachedData) /* Have it cached already, yay */ \
|
||||
return cachedData; \
|
||||
/* Have the rulenode deal */ \
|
||||
|
@ -740,7 +740,7 @@ PRBool nsStyleSet::BuildDefaultStyleData(nsPresContext* aPresContext)
|
||||
#define SSARG_PRESCONTEXT aPresContext
|
||||
|
||||
#define CREATE_DATA(name, type, args) \
|
||||
if (!(mDefaultStyleData.m##type##Data->m##name##Data = \
|
||||
if (!(mDefaultStyleData.m##type##Data->mStyleStructs[eStyleStruct_##name] = \
|
||||
new (aPresContext) nsStyle##name args)) \
|
||||
return PR_FALSE;
|
||||
|
||||
|
@ -51,30 +51,6 @@
|
||||
#include "nsTextFormatter.h"
|
||||
#include "nsCSSProps.h"
|
||||
|
||||
// XXX This is here because nsCachedStyleData is accessed outside of
|
||||
// the content module; e.g., by nsCSSFrameConstructor.
|
||||
#include "nsRuleNode.h"
|
||||
|
||||
nsCachedStyleData::StyleStructInfo
|
||||
nsCachedStyleData::gInfo[] = {
|
||||
|
||||
#define STYLE_STRUCT_INHERITED(name, checkdata_cb, ctor_args) \
|
||||
{ offsetof(nsCachedStyleData, mInheritedData), \
|
||||
offsetof(nsInheritedStyleData, m##name##Data), \
|
||||
PR_FALSE },
|
||||
#define STYLE_STRUCT_RESET(name, checkdata_cb, ctor_args) \
|
||||
{ offsetof(nsCachedStyleData, mResetData), \
|
||||
offsetof(nsResetStyleData, m##name##Data), \
|
||||
PR_TRUE },
|
||||
|
||||
#include "nsStyleStructList.h"
|
||||
|
||||
#undef STYLE_STRUCT_INHERITED
|
||||
#undef STYLE_STRUCT_RESET
|
||||
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
#define POSITIVE_SCALE_FACTOR 1.10 /* 10% */
|
||||
#define NEGATIVE_SCALE_FACTOR .90 /* 10% */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user