mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-24 16:17:29 +09:00
Issue #2828 - Part 11: Detach weighted rule data from cascade layer
This commit is contained in:
parent
a922ec0823
commit
cbb019a862
2 changed files with 89 additions and 57 deletions
|
|
@ -7,7 +7,7 @@
|
||||||
// We want page-sized arenas so there's no fragmentation involved.
|
// We want page-sized arenas so there's no fragmentation involved.
|
||||||
// Including plarena.h must come first to avoid it being included by some
|
// Including plarena.h must come first to avoid it being included by some
|
||||||
// header file thereby making PL_ARENA_CONST_ALIGN_MASK ineffective.
|
// header file thereby making PL_ARENA_CONST_ALIGN_MASK ineffective.
|
||||||
#define NS_CASCADELAYER_ARENA_BLOCK_SIZE (4096)
|
#define NS_WEIGHTEDRULEDATA_ARENA_BLOCK_SIZE (4096)
|
||||||
#include "plarena.h"
|
#include "plarena.h"
|
||||||
|
|
||||||
#include "RuleCascadeData.h"
|
#include "RuleCascadeData.h"
|
||||||
|
|
@ -1536,7 +1536,8 @@ InitWeightEntry(PLDHashEntryHdr* hdr, const void* key)
|
||||||
new (KnownNotNull, entry) RuleByWeightEntry();
|
new (KnownNotNull, entry) RuleByWeightEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ const PLDHashTableOps CascadeLayer::sRulesByWeightOps = {
|
/* static */ const PLDHashTableOps
|
||||||
|
CascadeLayer::WeightedRuleData::sRulesByWeightOps = {
|
||||||
HashIntKey,
|
HashIntKey,
|
||||||
MatchWeightEntry,
|
MatchWeightEntry,
|
||||||
PLDHashTable::MoveEntryStub,
|
PLDHashTable::MoveEntryStub,
|
||||||
|
|
@ -1544,6 +1545,72 @@ InitWeightEntry(PLDHashEntryHdr* hdr, const void* key)
|
||||||
InitWeightEntry
|
InitWeightEntry
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CascadeLayer::WeightedRuleData::WeightedRuleData()
|
||||||
|
: mRulesByWeight(&sRulesByWeightOps, sizeof(RuleByWeightEntry), 32)
|
||||||
|
{
|
||||||
|
// Initialize our arena
|
||||||
|
PL_INIT_ARENA_POOL(
|
||||||
|
&mArena, "WeightedRuleDataArena", NS_WEIGHTEDRULEDATA_ARENA_BLOCK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
CascadeLayer::WeightedRuleData::~WeightedRuleData()
|
||||||
|
{
|
||||||
|
PL_FinishArenaPool(&mArena);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
CompareWeightData(const void* aArg1, const void* aArg2, void* closure)
|
||||||
|
{
|
||||||
|
const PerWeightData* arg1 = static_cast<const PerWeightData*>(aArg1);
|
||||||
|
const PerWeightData* arg2 = static_cast<const PerWeightData*>(aArg2);
|
||||||
|
return arg1->mWeight - arg2->mWeight; // put lower weight first
|
||||||
|
}
|
||||||
|
|
||||||
|
UniquePtr<PerWeightData[]>
|
||||||
|
CascadeLayer::WeightedRuleData::Consume(nsTArray<css::StyleRule*>& aStyleRules)
|
||||||
|
{
|
||||||
|
for (css::StyleRule* styleRule : aStyleRules) {
|
||||||
|
for (nsCSSSelectorList* sel = styleRule->Selector(); sel;
|
||||||
|
sel = sel->mNext) {
|
||||||
|
int32_t weight = sel->mWeight;
|
||||||
|
auto entry = static_cast<RuleByWeightEntry*>(
|
||||||
|
mRulesByWeight.Add(NS_INT32_TO_PTR(weight), fallible));
|
||||||
|
if (!entry) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
entry->data.mWeight = weight;
|
||||||
|
// entry->data.mRuleSelectorPairs should be linked in forward order;
|
||||||
|
// entry->data.mTail is the slot to write to.
|
||||||
|
auto* newItem =
|
||||||
|
new (mArena) PerWeightDataListItem(styleRule, sel->mSelectors);
|
||||||
|
if (newItem) {
|
||||||
|
*(entry->data.mTail) = newItem;
|
||||||
|
entry->data.mTail = &newItem->mNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// There's no point in keeping pointers to the style rules around
|
||||||
|
// after we've consumed them, so clear the array.
|
||||||
|
aStyleRules.Clear();
|
||||||
|
|
||||||
|
// Sort the hash table of per-weight linked lists by weight.
|
||||||
|
uint32_t weightCount = mRulesByWeight.EntryCount();
|
||||||
|
auto weightArray = MakeUnique<PerWeightData[]>(weightCount);
|
||||||
|
int32_t j = 0;
|
||||||
|
for (auto iter = mRulesByWeight.Iter(); !iter.Done(); iter.Next()) {
|
||||||
|
auto entry = static_cast<const RuleByWeightEntry*>(iter.Get());
|
||||||
|
weightArray[j++] = entry->data;
|
||||||
|
}
|
||||||
|
NS_QuickSort(weightArray.get(),
|
||||||
|
weightCount,
|
||||||
|
sizeof(PerWeightData),
|
||||||
|
CompareWeightData,
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
return weightArray;
|
||||||
|
}
|
||||||
|
|
||||||
CascadeLayer::CascadeLayer(nsPresContext* aPresContext,
|
CascadeLayer::CascadeLayer(nsPresContext* aPresContext,
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
CascadeLayer* aParent,
|
CascadeLayer* aParent,
|
||||||
|
|
@ -1564,21 +1631,15 @@ CascadeLayer::CascadeLayer(nsPresContext* aPresContext,
|
||||||
, mDocumentCacheKey(aDocumentKey)
|
, mDocumentCacheKey(aDocumentKey)
|
||||||
, mSheetType(aSheetType)
|
, mSheetType(aSheetType)
|
||||||
, mMustGatherDocumentRules(aMustGatherDocumentRules)
|
, mMustGatherDocumentRules(aMustGatherDocumentRules)
|
||||||
, mRulesByWeight(&sRulesByWeightOps, sizeof(RuleByWeightEntry), 32)
|
|
||||||
, mCacheKey(aCacheKey)
|
, mCacheKey(aCacheKey)
|
||||||
{
|
{
|
||||||
mData = new RuleCascadeData(eCompatibility_NavQuirks ==
|
mData = new RuleCascadeData(eCompatibility_NavQuirks ==
|
||||||
mPresContext->CompatibilityMode());
|
mPresContext->CompatibilityMode());
|
||||||
|
|
||||||
// Initialize our arena
|
|
||||||
PL_INIT_ARENA_POOL(
|
|
||||||
&mArena, "CascadeLayerArena", NS_CASCADELAYER_ARENA_BLOCK_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CascadeLayer::~CascadeLayer()
|
CascadeLayer::~CascadeLayer()
|
||||||
{
|
{
|
||||||
delete mData;
|
delete mData;
|
||||||
PL_FinishArenaPool(&mArena);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CascadeLayer*
|
CascadeLayer*
|
||||||
|
|
@ -1635,57 +1696,17 @@ CascadeLayer::CreateAnonymousChildLayer()
|
||||||
return childLayer;
|
return childLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
CompareWeightData(const void* aArg1, const void* aArg2, void* closure)
|
|
||||||
{
|
|
||||||
const PerWeightData* arg1 = static_cast<const PerWeightData*>(aArg1);
|
|
||||||
const PerWeightData* arg2 = static_cast<const PerWeightData*>(aArg2);
|
|
||||||
return arg1->mWeight - arg2->mWeight; // put lower weight first
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CascadeLayer::AddRules()
|
CascadeLayer::AddRules()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!mRulesAdded, "Rule cascade data already filled");
|
MOZ_ASSERT(!mRulesAdded, "Rule cascade data already filled");
|
||||||
|
|
||||||
for (css::StyleRule* styleRule : mStyleRules) {
|
WeightedRuleData ruleData;
|
||||||
for (nsCSSSelectorList* sel = styleRule->Selector(); sel;
|
auto weightArray = ruleData.Consume(mStyleRules);
|
||||||
sel = sel->mNext) {
|
|
||||||
int32_t weight = sel->mWeight;
|
|
||||||
auto entry = static_cast<RuleByWeightEntry*>(
|
|
||||||
mRulesByWeight.Add(NS_INT32_TO_PTR(weight), fallible));
|
|
||||||
if (!entry) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
entry->data.mWeight = weight;
|
|
||||||
// entry->data.mRuleSelectorPairs should be linked in forward order;
|
|
||||||
// entry->data.mTail is the slot to write to.
|
|
||||||
auto* newItem =
|
|
||||||
new (mArena) PerWeightDataListItem(styleRule, sel->mSelectors);
|
|
||||||
if (newItem) {
|
|
||||||
*(entry->data.mTail) = newItem;
|
|
||||||
entry->data.mTail = &newItem->mNext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort the hash table of per-weight linked lists by weight.
|
|
||||||
uint32_t weightCount = mRulesByWeight.EntryCount();
|
|
||||||
auto weightArray = MakeUnique<PerWeightData[]>(weightCount);
|
|
||||||
int32_t j = 0;
|
|
||||||
for (auto iter = mRulesByWeight.Iter(); !iter.Done(); iter.Next()) {
|
|
||||||
auto entry = static_cast<const RuleByWeightEntry*>(iter.Get());
|
|
||||||
weightArray[j++] = entry->data;
|
|
||||||
}
|
|
||||||
NS_QuickSort(weightArray.get(),
|
|
||||||
weightCount,
|
|
||||||
sizeof(PerWeightData),
|
|
||||||
CompareWeightData,
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
// Put things into the rule hash.
|
// Put things into the rule hash.
|
||||||
// The primary sort is by weight...
|
// The primary sort is by weight...
|
||||||
for (uint32_t i = 0; i < weightCount; ++i) {
|
for (uint32_t i = 0; i < ruleData.mRulesByWeight.EntryCount(); ++i) {
|
||||||
// and the secondary sort is by order. mRuleSelectorPairs is already in
|
// and the secondary sort is by order. mRuleSelectorPairs is already in
|
||||||
// the right order..
|
// the right order..
|
||||||
for (PerWeightDataListItem* cur = weightArray[i].mRuleSelectorPairs; cur;
|
for (PerWeightDataListItem* cur = weightArray[i].mRuleSelectorPairs; cur;
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
struct nsFontFaceRuleContainer;
|
struct nsFontFaceRuleContainer;
|
||||||
|
struct PerWeightData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A struct representing a given CSS rule and a particular selector
|
* A struct representing a given CSS rule and a particular selector
|
||||||
|
|
@ -350,11 +351,6 @@ struct CascadeLayer
|
||||||
SheetType mSheetType;
|
SheetType mSheetType;
|
||||||
bool mMustGatherDocumentRules;
|
bool mMustGatherDocumentRules;
|
||||||
|
|
||||||
PLArenaPool mArena;
|
|
||||||
// Hooray, a manual PLDHashTable since nsClassHashtable doesn't
|
|
||||||
// provide a getter that gives me a *reference* to the value.
|
|
||||||
PLDHashTable mRulesByWeight; // of PerWeightDataListItem linked lists
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
CascadeLayer* mParent;
|
CascadeLayer* mParent;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -370,7 +366,22 @@ struct CascadeLayer
|
||||||
void AddRules();
|
void AddRules();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const PLDHashTableOps sRulesByWeightOps;
|
struct WeightedRuleData
|
||||||
|
{
|
||||||
|
WeightedRuleData();
|
||||||
|
~WeightedRuleData();
|
||||||
|
|
||||||
|
UniquePtr<PerWeightData[]> Consume(nsTArray<css::StyleRule*>& aStyleRules);
|
||||||
|
|
||||||
|
PLArenaPool mArena;
|
||||||
|
// Hooray, a manual PLDHashTable since nsClassHashtable doesn't
|
||||||
|
// provide a getter that gives me a *reference* to the value.
|
||||||
|
PLDHashTable mRulesByWeight; // of PerWeightDataListItem linked lists
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const PLDHashTableOps sRulesByWeightOps;
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* RuleCascadeData_h___ */
|
#endif /* RuleCascadeData_h___ */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue