diff --git a/content/xul/templates/src/nsRuleNetwork.cpp b/content/xul/templates/src/nsRuleNetwork.cpp index ddd092e8951..2e49f19496a 100644 --- a/content/xul/templates/src/nsRuleNetwork.cpp +++ b/content/xul/templates/src/nsRuleNetwork.cpp @@ -598,7 +598,7 @@ RootNode::Propogate(const InstantiationSet& aInstantiations, void* aClosure) } nsresult -RootNode::Constrain(InstantiationSet& aInstantiations) +RootNode::Constrain(InstantiationSet& aInstantiations, void* aClosure) { return NS_OK; } @@ -676,7 +676,7 @@ JoinNode::Propogate(const InstantiationSet& aInstantiations, void* aClosure) if (! instantiations.Empty()) { // propogate consistency checking back up the tree - rv = test->Constrain(instantiations); + rv = test->Constrain(instantiations, aClosure); if (NS_FAILED(rv)) return rv; NodeSet::Iterator last = mKids.Last(); @@ -753,7 +753,7 @@ JoinNode::Bind(InstantiationSet& aInstantiations, PRBool* aDidBind) } nsresult -JoinNode::Constrain(InstantiationSet& aInstantiations) +JoinNode::Constrain(InstantiationSet& aInstantiations, void* aClosure) { if (aInstantiations.Empty()) return NS_OK; @@ -782,7 +782,7 @@ JoinNode::Constrain(InstantiationSet& aInstantiations) last = mLeftParent; } - rv = first->Constrain(aInstantiations); + rv = first->Constrain(aInstantiations, aClosure); if (NS_FAILED(rv)) return rv; if (! didBind) { @@ -792,7 +792,7 @@ JoinNode::Constrain(InstantiationSet& aInstantiations) NS_ASSERTION(didBind, "uh oh, still no binding"); } - rv = last->Constrain(aInstantiations); + rv = last->Constrain(aInstantiations, aClosure); if (NS_FAILED(rv)) return rv; if (! didBind) { @@ -865,7 +865,7 @@ TestNode::Propogate(const InstantiationSet& aInstantiations, void* aClosure) nsresult rv; InstantiationSet instantiations = aInstantiations; - rv = FilterInstantiations(instantiations); + rv = FilterInstantiations(instantiations, aClosure); if (NS_FAILED(rv)) return rv; if (! instantiations.Empty()) { @@ -879,17 +879,17 @@ TestNode::Propogate(const InstantiationSet& aInstantiations, void* aClosure) nsresult -TestNode::Constrain(InstantiationSet& aInstantiations) +TestNode::Constrain(InstantiationSet& aInstantiations, void* aClosure) { nsresult rv; - rv = FilterInstantiations(aInstantiations); + rv = FilterInstantiations(aInstantiations, aClosure); if (NS_FAILED(rv)) return rv; if (! aInstantiations.Empty()) { // if we still have instantiations, then ride 'em on up to the // parent to narrow them. - rv = mParent->Constrain(aInstantiations); + rv = mParent->Constrain(aInstantiations, aClosure); } else { rv = NS_OK; diff --git a/content/xul/templates/src/nsRuleNetwork.h b/content/xul/templates/src/nsRuleNetwork.h index 4c667869d5e..decb6a046a4 100644 --- a/content/xul/templates/src/nsRuleNetwork.h +++ b/content/xul/templates/src/nsRuleNetwork.h @@ -137,7 +137,7 @@ public: virtual const char* Type() const = 0; virtual PLHashNumber Hash() const = 0; virtual PRBool Equals(const MemoryElement& aElement) const = 0; - virtual MemoryElement* Clone() const = 0; + virtual MemoryElement* Clone(void* aPool) const = 0; PRBool operator==(const MemoryElement& aMemoryElement) const { return Equals(aMemoryElement); @@ -719,7 +719,7 @@ class InnerNode : public ReteNode { public: // "upward" propogations - virtual nsresult Constrain(InstantiationSet& aInstantiations) = 0; + virtual nsresult Constrain(InstantiationSet& aInstantiations, void* aClosure) = 0; virtual nsresult GetAncestorVariables(VariableSet& aVariables) const = 0; @@ -744,7 +744,7 @@ public: virtual nsresult Propogate(const InstantiationSet& aInstantiations, void* aClosure); // "upward" propogations - virtual nsresult Constrain(InstantiationSet& aInstantiations); + virtual nsresult Constrain(InstantiationSet& aInstantiations, void* aClosure); virtual nsresult GetAncestorVariables(VariableSet& aVariables) const; @@ -773,7 +773,7 @@ public: virtual nsresult Propogate(const InstantiationSet& aInstantiations, void* aClosure); // "upward" propogations - virtual nsresult Constrain(InstantiationSet& aInstantiations); + virtual nsresult Constrain(InstantiationSet& aInstantiations, void* aClosure); virtual nsresult GetAncestorVariables(VariableSet& aVariables) const; @@ -808,10 +808,10 @@ public: virtual nsresult Propogate(const InstantiationSet& aInstantiations, void* aClosure); // "upward" propogations - virtual nsresult Constrain(InstantiationSet& aInstantiations); + virtual nsresult Constrain(InstantiationSet& aInstantiations, void* aClosure); // instantiation filtering - virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations) const = 0; //XXX probably better named "ApplyConstraints" or "Discrminiate" or something + virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const = 0; //XXX probably better named "ApplyConstraints" or "Discrminiate" or something virtual nsresult GetAncestorVariables(VariableSet& aVariables) const; diff --git a/content/xul/templates/src/nsXULTemplateBuilder.cpp b/content/xul/templates/src/nsXULTemplateBuilder.cpp index 22be81db00f..033ebd314f5 100644 --- a/content/xul/templates/src/nsXULTemplateBuilder.cpp +++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp @@ -44,6 +44,7 @@ #include "nsCOMPtr.h" #include "nsCRT.h" +#include "nsFixedSizeAllocator.h" #include "nsIAtom.h" #include "nsIContent.h" #include "nsIDOMElement.h" @@ -555,6 +556,12 @@ protected: PRInt32 mRefCnt; public: + static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) { + return aAllocator.Alloc(aSize); } + + static void operator delete(void* aPtr, size_t aSize) { + nsFixedSizeAllocator::Free(aPtr, aSize); } + Match(const Rule* aRule, const Instantiation& aInstantiation, nsBindingSet aBindings) : mRefCnt(1), mRule(aRule), @@ -617,6 +624,12 @@ private: protected: struct MatchList { + static void* operator new(size_t aSize, nsFixedSizeAllocator& aPool) { + return aPool.Alloc(aSize); } + + static void operator delete(void* aPtr, size_t aSize) { + nsFixedSizeAllocator::Free(aPtr, aSize); } + Match* mMatch; MatchList* mNext; MatchList* mPrev; @@ -624,7 +637,7 @@ protected: MatchList mHead; - // XXXwaterson Lazily create this if we pass a size threshold. + // Lazily created when we pass a size threshold. PLHashTable* mMatches; PRInt32 mCount; @@ -641,7 +654,31 @@ protected: enum { kHashTableThreshold = 8 }; + static PLHashAllocOps gAllocOps; + + static void* PR_CALLBACK AllocTable(void* aPool, PRSize aSize) { + return new char[aSize]; } + + static void PR_CALLBACK FreeTable(void* aPool, void* aItem) { + delete[] NS_STATIC_CAST(char*, aItem); } + + static PLHashEntry* PR_CALLBACK AllocEntry(void* aPool, const void* aKey) { + nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool); + PLHashEntry* entry = NS_STATIC_CAST(PLHashEntry*, pool->Alloc(sizeof(PLHashEntry))); + return entry; } + + static void PR_CALLBACK FreeEntry(void* aPool, PLHashEntry* aEntry, PRUintn aFlag) { + if (aFlag == HT_FREE_ENTRY) + nsFixedSizeAllocator::Free(aEntry, sizeof(PLHashEntry)); } + public: + // Used to initialize the nsFixedSizeAllocator that's used to pool + // entries. + enum { + kEntrySize = sizeof(MatchList), + kIndexSize = sizeof(PLHashEntry) + }; + class ConstIterator { protected: friend class Iterator; // XXXwaterson so broken. @@ -740,16 +777,18 @@ public: const Match* GetLastMatch() const { return mLastMatch; } void SetLastMatch(const Match* aMatch) { mLastMatch = aMatch; } - Iterator Insert(Iterator aIterator, Match* aMatch); + Iterator Insert(nsFixedSizeAllocator& aPool, Iterator aIterator, Match* aMatch); - Iterator Add(Match* aMatch) { - return Insert(Last(), aMatch); } + Iterator Add(nsFixedSizeAllocator& aPool, Match* aMatch) { + return Insert(aPool, Last(), aMatch); } void Clear(); Iterator Erase(Iterator aIterator); }; +PLHashAllocOps MatchSet::gAllocOps = { + AllocTable, FreeTable, AllocEntry, FreeEntry }; MatchSet::MatchSet() @@ -777,7 +816,7 @@ MatchSet::~MatchSet() MatchSet::Iterator -MatchSet::Insert(Iterator aIterator, Match* aMatch) +MatchSet::Insert(nsFixedSizeAllocator& aPool, Iterator aIterator, Match* aMatch) { if (++mCount > kHashTableThreshold && !mMatches) { // If we've exceeded a high-water mark, then hash everything. @@ -785,8 +824,8 @@ MatchSet::Insert(Iterator aIterator, Match* aMatch) HashMatch, CompareMatches, PL_CompareValues, - nsnull /* XXXwaterson use an arena */, - nsnull); + &gAllocOps, + &aPool); Iterator last = Last(); for (Iterator match = First(); match != last; ++match) { @@ -800,7 +839,7 @@ MatchSet::Insert(Iterator aIterator, Match* aMatch) } } - MatchList* newelement = new MatchList(); + MatchList* newelement = new (aPool) MatchList(); if (newelement) { newelement->mMatch = aMatch; aMatch->AddRef(); @@ -996,6 +1035,8 @@ protected: PLHashTable* mTable; Entry mHead; + nsFixedSizeAllocator mPool; + public: KeySet(); ~KeySet(); @@ -1045,53 +1086,56 @@ public: protected: static PLHashAllocOps gAllocOps; - static void* PR_CALLBACK AllocTable(void* aPool, PRSize aSize); - static void PR_CALLBACK FreeTable(void* aPool, void* aItem); - static PLHashEntry* PR_CALLBACK AllocEntry(void* aPool, const void* aKey); - static void PR_CALLBACK FreeEntry(void* aPool, PLHashEntry* aEntry, PRUintn aFlag); + static void* PR_CALLBACK AllocTable(void* aPool, PRSize aSize) { + return new char[aSize]; } + + static void PR_CALLBACK FreeTable(void* aPool, void* aItem) { + delete[] NS_STATIC_CAST(char*, aItem); } + + static PLHashEntry* PR_CALLBACK AllocEntry(void* aPool, const void* aKey) { + nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool); + const Key* key = NS_STATIC_CAST(const Key*, aKey); + + Entry* entry = NS_STATIC_CAST(Entry*, pool->Alloc(sizeof(Entry))); + if (! entry) + return nsnull; + + // Need to explicitly call ctor + entry->Entry::Entry(*key); + + return NS_REINTERPRET_CAST(PLHashEntry*, entry); } + + static void PR_CALLBACK FreeEntry(void* aPool, PLHashEntry* aEntry, PRUintn aFlag) { + if (aFlag == HT_FREE_ENTRY) { + Entry* entry = NS_REINTERPRET_CAST(Entry*, aEntry); + + // Need to explicitly call dtor + entry->Entry::~Entry(); + + nsFixedSizeAllocator::Free(entry, sizeof(Entry)); + } } }; PLHashAllocOps KeySet::gAllocOps = { - AllocTable, - FreeTable, - AllocEntry, - FreeEntry -}; + AllocTable, FreeTable, AllocEntry, FreeEntry }; -void* PR_CALLBACK -KeySet::AllocTable(void* aPool, PRSize aSize) -{ - return new char[aSize]; -} - -void PR_CALLBACK -KeySet::FreeTable(void* aPool, void* aItem) -{ - delete[] NS_STATIC_CAST(char*, aItem); -} - -PLHashEntry* PR_CALLBACK -KeySet::AllocEntry(void* aPool, const void* aKey) -{ - const Key* key = NS_STATIC_CAST(const Key*, aKey); - Entry* entry = new Entry(*key); - return NS_REINTERPRET_CAST(PLHashEntry*, entry); -} - -void PR_CALLBACK -KeySet::FreeEntry(void* aPool, PLHashEntry* aEntry, PRUintn aFlag) -{ - Entry* entry = NS_REINTERPRET_CAST(Entry*, aEntry); - delete entry; -} KeySet::KeySet() : mTable(nsnull) { mHead.mPrev = mHead.mNext = &mHead; - mTable = PL_NewHashTable(8, Key::HashKey, Key::CompareKeys, PL_CompareValues, - &gAllocOps, nsnull); + static const size_t kBucketSizes[] = { sizeof(Entry) }; + static const PRInt32 kNumBuckets = sizeof(kBucketSizes) / sizeof(size_t); + static const PRInt32 kInitialEntries = 8; + + static const PRInt32 kInitialPoolSize = + NS_SIZE_IN_HEAP(sizeof(Entry)) * kInitialEntries; + + mPool.Init("KeySet", kBucketSizes, kNumBuckets, kInitialPoolSize); + + mTable = PL_NewHashTable(kInitialEntries, Key::HashKey, Key::CompareKeys, + PL_CompareValues, &gAllocOps, &mPool); MOZ_COUNT_CTOR(KeySet); } @@ -1161,6 +1205,8 @@ public: void Clear(); + nsFixedSizeAllocator& GetPool() { return mPool; } + protected: nsresult Init(); nsresult Destroy(); @@ -1179,10 +1225,35 @@ protected: }; static PLHashAllocOps gMatchAllocOps; - static void* PR_CALLBACK AllocMatchTable(void* aPool, PRSize aSize); - static void PR_CALLBACK FreeMatchTable(void* aPool, void* aItem); - static PLHashEntry* PR_CALLBACK AllocMatchEntry(void* aPool, const void* aKey); - static void PR_CALLBACK FreeMatchEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag); + + static void* PR_CALLBACK AllocMatchTable(void* aPool, PRSize aSize) { + return new char[aSize]; } + + static void PR_CALLBACK FreeMatchTable(void* aPool, void* aItem) { + delete[] NS_STATIC_CAST(char*, aItem); } + + static PLHashEntry* PR_CALLBACK AllocMatchEntry(void* aPool, const void* aKey) { + nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool); + + MatchEntry* entry = NS_STATIC_CAST(MatchEntry*, pool->Alloc(sizeof(MatchEntry))); + if (! entry) + return nsnull; + + // Need to explicitly call ctor + entry->MatchEntry::MatchEntry(); + + entry->mKey = *NS_STATIC_CAST(const Key*, aKey); + return NS_REINTERPRET_CAST(PLHashEntry*, entry); } + + static void PR_CALLBACK FreeMatchEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag) { + if (aFlag == HT_FREE_ENTRY) { + MatchEntry* entry = NS_REINTERPRET_CAST(MatchEntry*, aHashEntry); + + // Need to explicitly call dtor + entry->MatchEntry::~MatchEntry(); + + nsFixedSizeAllocator::Free(entry, sizeof(MatchEntry)); + } } // Maps a MemoryElement to the matches that it supports PLHashTable* mSupport; @@ -1201,11 +1272,39 @@ protected: MatchSet mMatchSet; }; - static PLHashAllocOps gBindingAllocOps; - static void* PR_CALLBACK AllocSupportTable(void* aPool, PRSize aSize); - static void PR_CALLBACK FreeSupportTable(void* aPool, void* aItem); - static PLHashEntry* PR_CALLBACK AllocSupportEntry(void* aPool, const void* aKey); - static void PR_CALLBACK FreeSupportEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag); + static PLHashAllocOps gSupportAllocOps; + + static void* PR_CALLBACK AllocSupportTable(void* aPool, PRSize aSize) { + return new char[aSize]; } + + static void PR_CALLBACK FreeSupportTable(void* aPool, void* aItem) { + delete[] NS_STATIC_CAST(char*, aItem); } + + static PLHashEntry* PR_CALLBACK AllocSupportEntry(void* aPool, const void* aKey) { + nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool); + + SupportEntry* entry = NS_STATIC_CAST(SupportEntry*, pool->Alloc(sizeof(SupportEntry))); + if (! entry) + return nsnull; + + // Need to explicitly call ctor + entry->SupportEntry::SupportEntry(); + + const MemoryElement* element = NS_STATIC_CAST(const MemoryElement*, aKey); + entry->mElement = element->Clone(aPool); + + return NS_REINTERPRET_CAST(PLHashEntry*, entry); } + + static void PR_CALLBACK FreeSupportEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag) { + if (aFlag == HT_FREE_ENTRY) { + SupportEntry* entry = NS_REINTERPRET_CAST(SupportEntry*, aHashEntry); + + // Need to explicitly call dtor + entry->SupportEntry::~SupportEntry(); + + nsFixedSizeAllocator::Free(entry, sizeof(SupportEntry)); + } } + static PLHashNumber HashMemoryElement(const void* aBinding); static PRIntn CompareMemoryElements(const void* aLeft, const void* aRight); @@ -1232,91 +1331,45 @@ protected: static PLHashEntry* PR_CALLBACK AllocResourceEntry(void* aPool, const void* aKey) { - ResourceEntry* entry = new ResourceEntry; + nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool); + + ResourceEntry* entry = + NS_STATIC_CAST(ResourceEntry*, pool->Alloc(sizeof(ResourceEntry))); + + if (! entry) + return nsnull; + + // Need to explicitly call ctor + entry->ResourceEntry::ResourceEntry(); + return NS_REINTERPRET_CAST(PLHashEntry*, entry); } static void PR_CALLBACK FreeResourceEntry(void* aPool, PLHashEntry* aEntry, PRUintn aFlag) { - delete NS_REINTERPRET_CAST(ResourceEntry*, aEntry); } + if (aFlag == HT_FREE_ENTRY) { + ResourceEntry* entry = NS_REINTERPRET_CAST(ResourceEntry*, aEntry); + + // Need to explicitly call dtor + entry->ResourceEntry::~ResourceEntry(); + + nsFixedSizeAllocator::Free(entry, sizeof(ResourceEntry)); + } } static PLHashNumber HashPointer(const void* aKey) { return PLHashNumber(aKey) >> 3; } + + nsFixedSizeAllocator mPool; }; // Allocation operations for the match table PLHashAllocOps ConflictSet::gMatchAllocOps = { AllocMatchTable, FreeMatchTable, AllocMatchEntry, FreeMatchEntry }; - -void* PR_CALLBACK -ConflictSet::AllocMatchTable(void* aPool, PRSize aSize) -{ - return new char[aSize]; -} - -void PR_CALLBACK -ConflictSet::FreeMatchTable(void* aPool, void* aItem) -{ - delete[] NS_STATIC_CAST(char*, aItem); -} - -PLHashEntry* PR_CALLBACK -ConflictSet::AllocMatchEntry(void* aPool, const void* aKey) -{ - MatchEntry* entry = new MatchEntry(); - if (! entry) - return nsnull; - - entry->mKey = *NS_STATIC_CAST(const Key*, aKey); - return NS_REINTERPRET_CAST(PLHashEntry*, entry); -} - -void PR_CALLBACK -ConflictSet::FreeMatchEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag) -{ - MatchEntry* entry = NS_REINTERPRET_CAST(MatchEntry*, aHashEntry); - delete entry; -} - // Allocation operations for the bindings table -PLHashAllocOps ConflictSet::gBindingAllocOps = { +PLHashAllocOps ConflictSet::gSupportAllocOps = { AllocSupportTable, FreeSupportTable, AllocSupportEntry, FreeSupportEntry }; - -void* PR_CALLBACK -ConflictSet::AllocSupportTable(void* aPool, PRSize aSize) -{ - return new char[aSize]; -} - -void PR_CALLBACK -ConflictSet::FreeSupportTable(void* aPool, void* aItem) -{ - delete[] NS_STATIC_CAST(char*, aItem); -} - -PLHashEntry* PR_CALLBACK -ConflictSet::AllocSupportEntry(void* aPool, const void* aKey) -{ - SupportEntry* entry = new SupportEntry(); - if (! entry) - return nsnull; - - const MemoryElement* element = NS_STATIC_CAST(const MemoryElement*, aKey); - entry->mElement = element->Clone(); - - return NS_REINTERPRET_CAST(PLHashEntry*, entry); -} - -void PR_CALLBACK -ConflictSet::FreeSupportEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag) -{ - SupportEntry* entry = NS_REINTERPRET_CAST(SupportEntry*, aHashEntry); - delete entry; -} - - ConflictSet::ConflictSet() : mMatches(nsnull), mSupport(nsnull) { @@ -1332,26 +1385,48 @@ ConflictSet::~ConflictSet() nsresult ConflictSet::Init() { - mMatches = PL_NewHashTable(16 /* XXXwaterson we need a way to give a hint? */, + static const size_t kBucketSizes[] = { + sizeof(MatchEntry), + sizeof(SupportEntry), + sizeof(ResourceEntry), + MatchSet::kEntrySize, + MatchSet::kIndexSize + }; + + static const PRInt32 kNumBuckets = sizeof(kBucketSizes) / sizeof(size_t); + + static const PRInt32 kNumResourceElements = 64; + + static const PRInt32 kInitialSize = + (NS_SIZE_IN_HEAP(sizeof(MatchEntry)) + + NS_SIZE_IN_HEAP(sizeof(SupportEntry)) + + NS_SIZE_IN_HEAP(sizeof(ResourceEntry))) * kNumResourceElements + + (NS_SIZE_IN_HEAP(MatchSet::kEntrySize) + + NS_SIZE_IN_HEAP(MatchSet::kIndexSize)) * kNumResourceElements; + + mPool.Init("ConflictSet", kBucketSizes, kNumBuckets, kInitialSize); + + mMatches = PL_NewHashTable(kNumResourceElements /* XXXwaterson we need a way to give a hint? */, Key::HashKey, Key::CompareKeys, PL_CompareValues, &gMatchAllocOps, - nsnull /* XXXwaterson use an arena */); + &mPool); - mSupport = PL_NewHashTable(16, /* XXXwaterson need hint */ + mSupport = PL_NewHashTable(kNumResourceElements, /* XXXwaterson need hint */ HashMemoryElement, CompareMemoryElements, PL_CompareValues, - &gBindingAllocOps, - nsnull /* XXXwaterson use an arena */); + &gSupportAllocOps, + &mPool); - mResources = PL_NewHashTable(16 /* XXX arbitrary */, + mResources = PL_NewHashTable(kNumResourceElements /* XXX arbitrary */, HashPointer, PL_CompareValues, PL_CompareValues, &gResourceAllocOps, - nsnull /* XXX use an arena! */); + &mPool); + return NS_OK; } @@ -1400,7 +1475,7 @@ ConflictSet::Add(Match* aMatch, PRBool* aDidAddKey) } if (! set->Contains(*aMatch)) { - set->Add(aMatch); + set->Add(mPool, aMatch); *aDidAddKey = PR_TRUE; } } @@ -1433,7 +1508,7 @@ ConflictSet::Add(Match* aMatch, PRBool* aDidAddKey) } if (! set->Contains(*aMatch)) { - set->Add(aMatch); + set->Add(mPool, aMatch); } } } @@ -1471,7 +1546,7 @@ ConflictSet::Add(Match* aMatch, PRBool* aDidAddKey) set = &entry->mMatches; } - set->Add(aMatch); + set->Add(mPool, aMatch); } } @@ -1514,7 +1589,7 @@ ConflictSet::Remove(const MemoryElement& aMemoryElement, // instantiation we're to remove. for (MatchSet::Iterator match = set->First(); match != set->Last(); ++match) { // Note the retraction - aRetractedMatches.Add(match.operator->()); + aRetractedMatches.Add(mPool, match.operator->()); } // We'll eagerly remove it from the table. @@ -1545,7 +1620,7 @@ ConflictSet::Remove(const MemoryElement& aMemoryElement, set->FindMatchWithHighestPriority(); if (newmatch) - aNewMatches.Add(newmatch); + aNewMatches.Add(mPool, newmatch); break; } @@ -1600,11 +1675,11 @@ PLHashAllocOps ConflictSet::gResourceAllocOps = { class InstantiationNode : public ReteNode { public: - InstantiationNode(Rule* aRule, - ConflictSet* aConflictSet, + InstantiationNode(ConflictSet& aConflictSet, + Rule* aRule, nsIRDFDataSource* aDataSource) - : mRule(aRule), - mConflictSet(aConflictSet) {} + : mConflictSet(aConflictSet), + mRule(aRule) {} ~InstantiationNode(); @@ -1613,7 +1688,7 @@ public: protected: Rule* mRule; - ConflictSet* mConflictSet; + ConflictSet& mConflictSet; }; @@ -1637,12 +1712,12 @@ InstantiationNode::Propogate(const InstantiationSet& aInstantiations, void* aClo mRule->ComputeBindings(bindings); - Match* match = new Match(mRule, *inst, bindings); + Match* match = new (mConflictSet.GetPool()) Match(mRule, *inst, bindings); if (! match) return NS_ERROR_OUT_OF_MEMORY; PRBool didAddKey; - mConflictSet->Add(match, &didAddKey); + mConflictSet.Add(match, &didAddKey); match->Release(); @@ -1686,8 +1761,7 @@ public: /** * */ - virtual void Retract(ConflictSet& aConflictSet, - nsIRDFResource* aSource, + virtual void Retract(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget, MatchSet& aFirings, @@ -1721,6 +1795,7 @@ public: protected: PLHashTable* mMap; + nsFixedSizeAllocator mPool; struct Entry { PLHashEntry mHashEntry; @@ -1739,14 +1814,24 @@ protected: static PLHashEntry* PR_CALLBACK AllocEntry(void* aPool, const void* aKey) { - Entry* entry = new Entry; + nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool); + + Entry* entry = NS_STATIC_CAST(Entry*, pool->Alloc(sizeof(Entry))); + if (! entry) + return nsnull; + return NS_REINTERPRET_CAST(PLHashEntry*, entry); } static void PR_CALLBACK FreeEntry(void* aPool, PLHashEntry* aEntry, PRUintn aFlag) { - Entry* entry = NS_REINTERPRET_CAST(Entry*, aEntry); - entry->mMatch->Release(); - delete entry; } + if (aFlag == HT_FREE_ENTRY) { + Entry* entry = NS_REINTERPRET_CAST(Entry*, aEntry); + + if (entry->mMatch) + entry->mMatch->Release(); + + nsFixedSizeAllocator::Free(entry, sizeof(Entry)); + } } static PLHashNumber HashPointer(const void* aKey) { @@ -1758,12 +1843,22 @@ PLHashAllocOps ContentSupportMap::gAllocOps = { ContentSupportMap::ContentSupportMap() { - mMap = PL_NewHashTable(16 /* XXX arbitrary */, + static const size_t kBucketSizes[] = { sizeof(Entry) }; + static const PRInt32 kNumBuckets = sizeof(kBucketSizes) / sizeof(size_t); + + static const kInitialEntries = 16; // XXX arbitrary + + static const kInitialSize = + NS_SIZE_IN_HEAP(sizeof(Entry)) * kInitialEntries; + + mPool.Init("ContentSupportMap", kBucketSizes, kNumBuckets, kInitialSize); + + mMap = PL_NewHashTable(kInitialEntries, HashPointer, PL_CompareValues, PL_CompareValues, &gAllocOps, - nsnull /* XXX use an arena! */); + &mPool); } @@ -2106,22 +2201,30 @@ protected: { public: ContentIdTestNode(InnerNode* aParent, + ConflictSet& aConflictSet, nsIXULDocument* aDocument, nsIContent* aRoot, PRInt32 aContentVariable, PRInt32 aIdVariable) : TestNode(aParent), + mConflictSet(aConflictSet), mDocument(aDocument), mRoot(aRoot), mContentVariable(aContentVariable), mIdVariable(aIdVariable) {} - virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations) const; + virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const; virtual nsresult GetAncestorVariables(VariableSet& aVariables) const; class Element : public MemoryElement { public: + static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) { + return aAllocator.Alloc(aSize); } + + static void operator delete(void* aPtr, size_t aSize) { + nsFixedSizeAllocator::Free(aPtr, aSize); } + Element(nsIContent* aContent) : mContent(aContent) { MOZ_COUNT_CTOR(ContentIdTestNode::Element); } @@ -2141,14 +2244,16 @@ protected: } return PR_FALSE; } - virtual MemoryElement* Clone() const { - return new Element(mContent); } + virtual MemoryElement* Clone(void* aPool) const { + return new (*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool)) + Element(mContent); } protected: nsCOMPtr mContent; }; protected: + ConflictSet& mConflictSet; nsIXULDocument* mDocument; // [WEAK] because we know the document will outlive us nsCOMPtr mRoot; PRInt32 mContentVariable; @@ -2192,11 +2297,13 @@ class RDFPropertyTestNode : public RDFTestNode public: // Both source and target unbound (?source ^property ?target) RDFPropertyTestNode(InnerNode* aParent, + ConflictSet& aConflictSet, nsIRDFDataSource* aDataSource, PRInt32 aSourceVariable, nsIRDFResource* aProperty, PRInt32 aTargetVariable) : RDFTestNode(aParent), + mConflictSet(aConflictSet), mDataSource(aDataSource), mSourceVariable(aSourceVariable), mSource(nsnull), @@ -2206,11 +2313,13 @@ public: // Source bound, target unbound (source ^property ?target) RDFPropertyTestNode(InnerNode* aParent, + ConflictSet& aConflictSet, nsIRDFDataSource* aDataSource, nsIRDFResource* aSource, nsIRDFResource* aProperty, PRInt32 aTargetVariable) : RDFTestNode(aParent), + mConflictSet(aConflictSet), mDataSource(aDataSource), mSourceVariable(0), mSource(aSource), @@ -2220,11 +2329,13 @@ public: // Source unbound, target bound (?source ^property target) RDFPropertyTestNode(InnerNode* aParent, + ConflictSet& aConflictSet, nsIRDFDataSource* aDataSource, PRInt32 aSourceVariable, nsIRDFResource* aProperty, nsIRDFNode* aTarget) : RDFTestNode(aParent), + mConflictSet(aConflictSet), mDataSource(aDataSource), mSourceVariable(aSourceVariable), mSource(nsnull), @@ -2232,7 +2343,7 @@ public: mTargetVariable(0), mTarget(aTarget) {} - virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations) const; + virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const; virtual nsresult GetAncestorVariables(VariableSet& aVariables) const; @@ -2243,8 +2354,7 @@ public: Instantiation& aInitialBindings) const; virtual void - Retract(ConflictSet& aConflictSet, - nsIRDFResource* aSource, + Retract(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget, MatchSet& aFirings, @@ -2253,6 +2363,12 @@ public: class Element : public MemoryElement { public: + static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) { + return aAllocator.Alloc(aSize); } + + static void operator delete(void* aPtr, size_t aSize) { + nsFixedSizeAllocator::Free(aPtr, aSize); } + Element(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget) @@ -2280,8 +2396,9 @@ public: } return PR_FALSE; } - virtual MemoryElement* Clone() const { - return new Element(mSource, mProperty, mTarget); } + virtual MemoryElement* Clone(void* aPool) const { + return new (*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool)) + Element(mSource, mProperty, mTarget); } protected: nsCOMPtr mSource; @@ -2290,6 +2407,7 @@ public: }; protected: + ConflictSet& mConflictSet; nsCOMPtr mDataSource; PRInt32 mSourceVariable; nsCOMPtr mSource; @@ -2300,7 +2418,7 @@ protected: nsresult -RDFPropertyTestNode::FilterInstantiations(InstantiationSet& aInstantiations) const +RDFPropertyTestNode::FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const { nsresult rv; @@ -2340,9 +2458,15 @@ RDFPropertyTestNode::FilterInstantiations(InstantiationSet& aInstantiations) con if (hasAssertion) { // it's consistent. - inst->AddSupportingElement(new Element(VALUE_TO_IRDFRESOURCE(sourceValue), - mProperty, - VALUE_TO_IRDFNODE(targetValue))); + Element* element = new (mConflictSet.GetPool()) + Element(VALUE_TO_IRDFRESOURCE(sourceValue), + mProperty, + VALUE_TO_IRDFNODE(targetValue)); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + inst->AddSupportingElement(element); } else { // it's inconsistent. remove it. @@ -2408,9 +2532,17 @@ RDFPropertyTestNode::FilterInstantiations(InstantiationSet& aInstantiations) con // introduced. Ownership will be transferred to the Instantiation newinst = *inst; newinst.AddBinding(variable, value); - newinst.AddSupportingElement(new Element(VALUE_TO_IRDFRESOURCE(sourceValue), - mProperty, - VALUE_TO_IRDFNODE(targetValue))); + + Element* element = new (mConflictSet.GetPool()) + Element(VALUE_TO_IRDFRESOURCE(sourceValue), + mProperty, + VALUE_TO_IRDFNODE(targetValue)); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + newinst.AddSupportingElement(element); + aInstantiations.Insert(inst, newinst); } @@ -2470,15 +2602,14 @@ RDFPropertyTestNode::CanPropogate(nsIRDFResource* aSource, } void -RDFPropertyTestNode::Retract(ConflictSet& aConflictSet, - nsIRDFResource* aSource, +RDFPropertyTestNode::Retract(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget, MatchSet& aFirings, MatchSet& aRetractions) const { if (aProperty == mProperty.get()) { - aConflictSet.Remove(Element(aSource, aProperty, aTarget), aFirings, aRetractions); + mConflictSet.Remove(Element(aSource, aProperty, aTarget), aFirings, aRetractions); } } @@ -2489,17 +2620,19 @@ class RDFContainerMemberTestNode : public RDFTestNode { public: RDFContainerMemberTestNode(InnerNode* aParent, + ConflictSet& aConflictSet, nsIRDFDataSource* aDataSource, const PropertySet& aMembershipProperties, PRInt32 aContainerVariable, PRInt32 aMemberVariable) : RDFTestNode(aParent), + mConflictSet(aConflictSet), mDataSource(aDataSource), mMembershipProperties(aMembershipProperties), mContainerVariable(aContainerVariable), mMemberVariable(aMemberVariable) {} - virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations) const; + virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const; virtual nsresult GetAncestorVariables(VariableSet& aVariables) const; @@ -2510,8 +2643,7 @@ public: Instantiation& aInitialBindings) const; virtual void - Retract(ConflictSet& aConflictSet, - nsIRDFResource* aSource, + Retract(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget, MatchSet& aFirings, @@ -2519,6 +2651,12 @@ public: class Element : public MemoryElement { public: + static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) { + return aAllocator.Alloc(aSize); } + + static void operator delete(void* aPtr, size_t aSize) { + nsFixedSizeAllocator::Free(aPtr, aSize); } + Element(nsIRDFResource* aContainer, nsIRDFNode* aMember) : mContainer(aContainer), @@ -2541,8 +2679,9 @@ public: } return PR_FALSE; } - virtual MemoryElement* Clone() const { - return new Element(mContainer, mMember); } + virtual MemoryElement* Clone(void* aPool) const { + return new (*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool)) + Element(mContainer, mMember); } protected: nsCOMPtr mContainer; @@ -2550,6 +2689,7 @@ public: }; protected: + ConflictSet& mConflictSet; nsCOMPtr mDataSource; const PropertySet& mMembershipProperties; PRInt32 mContainerVariable; @@ -2557,7 +2697,7 @@ protected: }; nsresult -RDFContainerMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiations) const +RDFContainerMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const { // XXX Uh, factor me, please! nsresult rv; @@ -2637,8 +2777,14 @@ RDFContainerMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiatio if (isconsistent) { // Add a memory element to our set-of-support. - inst->AddSupportingElement(new Element(VALUE_TO_IRDFRESOURCE(containerValue), - VALUE_TO_IRDFNODE(memberValue))); + Element* element = new (mConflictSet.GetPool()) + Element(VALUE_TO_IRDFRESOURCE(containerValue), + VALUE_TO_IRDFNODE(memberValue)); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + inst->AddSupportingElement(element); } else { // it's inconsistent. remove it. @@ -2675,8 +2821,15 @@ RDFContainerMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiatio Instantiation newinst = *inst; newinst.AddBinding(mMemberVariable, Value(node.get())); - newinst.AddSupportingElement(new Element(VALUE_TO_IRDFRESOURCE(containerValue), - node)); + + Element* element = new (mConflictSet.GetPool()) + Element(VALUE_TO_IRDFRESOURCE(containerValue), node); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + newinst.AddSupportingElement(element); + aInstantiations.Insert(inst, newinst); } } @@ -2749,7 +2902,15 @@ RDFContainerMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiatio // Add a new instantiation Instantiation newinst = *inst; newinst.AddBinding(mContainerVariable, Value(source.get())); - newinst.AddSupportingElement(new Element(source, VALUE_TO_IRDFNODE(memberValue))); + + Element* element = new (mConflictSet.GetPool()) + Element(source, VALUE_TO_IRDFNODE(memberValue)); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + newinst.AddSupportingElement(element); + aInstantiations.Insert(inst, newinst); } } @@ -2814,14 +2975,24 @@ RDFContainerMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiatio // introduced. Ownership will be transferred to the Instantiation newinst = *inst; newinst.AddBinding(variable, value); + + Element* element; if (hasContainerBinding) { - newinst.AddSupportingElement(new Element(VALUE_TO_IRDFRESOURCE(containerValue), - VALUE_TO_IRDFNODE(value))); + element = new (mConflictSet.GetPool()) + Element(VALUE_TO_IRDFRESOURCE(containerValue), + VALUE_TO_IRDFNODE(value)); } else { - newinst.AddSupportingElement(new Element(VALUE_TO_IRDFRESOURCE(value), - VALUE_TO_IRDFNODE(memberValue))); + element = new (mConflictSet.GetPool()) + Element(VALUE_TO_IRDFRESOURCE(value), + VALUE_TO_IRDFNODE(memberValue)); } + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + newinst.AddSupportingElement(element); + aInstantiations.Insert(inst, newinst); } } @@ -2883,8 +3054,7 @@ RDFContainerMemberTestNode::CanPropogate(nsIRDFResource* aSource, } void -RDFContainerMemberTestNode::Retract(ConflictSet& aConflictSet, - nsIRDFResource* aSource, +RDFContainerMemberTestNode::Retract(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget, MatchSet& aFirings, @@ -2902,7 +3072,7 @@ RDFContainerMemberTestNode::Retract(ConflictSet& aConflictSet, } if (canretract) { - aConflictSet.Remove(Element(aSource, aTarget), aFirings, aRetractions); + mConflictSet.Remove(Element(aSource, aTarget), aFirings, aRetractions); } } @@ -2914,19 +3084,21 @@ public: enum Test { eFalse, eTrue, eDontCare }; RDFContainerInstanceTestNode(InnerNode* aParent, + ConflictSet& aConflictSet, nsIRDFDataSource* aDataSource, const PropertySet& aMembershipProperties, PRInt32 aContainerVariable, Test aContainer, Test aEmpty) : RDFTestNode(aParent), + mConflictSet(aConflictSet), mDataSource(aDataSource), mMembershipProperties(aMembershipProperties), mContainerVariable(aContainerVariable), mContainer(aContainer), mEmpty(aEmpty) {} - virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations) const; + virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const; virtual nsresult GetAncestorVariables(VariableSet& aVariables) const; @@ -2937,8 +3109,7 @@ public: Instantiation& aInitialBindings) const; virtual void - Retract(ConflictSet& aConflictSet, - nsIRDFResource* aSource, + Retract(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget, MatchSet& aFirings, @@ -2947,6 +3118,12 @@ public: class Element : public MemoryElement { public: + static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) { + return aAllocator.Alloc(aSize); } + + static void operator delete(void* aPtr, size_t aSize) { + nsFixedSizeAllocator::Free(aPtr, aSize); } + Element(nsIRDFResource* aContainer, Test aContainerTest, Test aEmptyTest) @@ -2974,8 +3151,9 @@ public: } return PR_FALSE; } - virtual MemoryElement* Clone() const { - return new Element(mContainer, mContainerTest, mEmptyTest); } + virtual MemoryElement* Clone(void* aPool) const { + return new (*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool)) + Element(mContainer, mContainerTest, mEmptyTest); } protected: nsCOMPtr mContainer; @@ -2984,6 +3162,7 @@ public: }; protected: + ConflictSet& mConflictSet; nsCOMPtr mDataSource; const PropertySet& mMembershipProperties; PRInt32 mContainerVariable; @@ -2992,7 +3171,7 @@ protected: }; nsresult -RDFContainerInstanceTestNode::FilterInstantiations(InstantiationSet& aInstantiations) const +RDFContainerInstanceTestNode::FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const { nsresult rv; @@ -3049,8 +3228,14 @@ RDFContainerInstanceTestNode::FilterInstantiations(InstantiationSet& aInstantiat } if (empty == mEmpty) { - inst->AddSupportingElement(new Element(VALUE_TO_IRDFRESOURCE(value), - mContainer, mEmpty)); + Element* element = new (mConflictSet.GetPool()) + Element(VALUE_TO_IRDFRESOURCE(value), + mContainer, mEmpty); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + inst->AddSupportingElement(element); } else { aInstantiations.Erase(inst--); @@ -3100,8 +3285,14 @@ RDFContainerInstanceTestNode::FilterInstantiations(InstantiationSet& aInstantiat } if (container == mContainer) { - inst->AddSupportingElement(new Element(VALUE_TO_IRDFRESOURCE(value), - mContainer, mEmpty)); + Element* element = new (mConflictSet.GetPool()) + Element(VALUE_TO_IRDFRESOURCE(value), mContainer, mEmpty); + + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + inst->AddSupportingElement(element); } else { aInstantiations.Erase(inst--); @@ -3150,8 +3341,7 @@ RDFContainerInstanceTestNode::CanPropogate(nsIRDFResource* aSource, } void -RDFContainerInstanceTestNode::Retract(ConflictSet& aConflictSet, - nsIRDFResource* aSource, +RDFContainerInstanceTestNode::Retract(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget, MatchSet& aFirings, @@ -3159,7 +3349,7 @@ RDFContainerInstanceTestNode::Retract(ConflictSet& aConflictSet, { // XXXwaterson oof. complicated. figure this out. if (0) { - aConflictSet.Remove(Element(aSource, mContainer, mEmpty), aFirings, aRetractions); + mConflictSet.Remove(Element(aSource, mContainer, mEmpty), aFirings, aRetractions); } } @@ -3169,23 +3359,26 @@ class ContentTagTestNode : public TestNode { public: ContentTagTestNode(InnerNode* aParent, + ConflictSet& aConflictSet, PRInt32 aContentVariable, nsIAtom* aTag) : TestNode(aParent), + mConflictSet(aConflictSet), mContentVariable(aContentVariable), mTag(aTag) {} - virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations) const; + virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const; virtual nsresult GetAncestorVariables(VariableSet& aVariables) const; protected: + ConflictSet& mConflictSet; PRInt32 mContentVariable; nsCOMPtr mTag; }; nsresult -ContentTagTestNode::FilterInstantiations(InstantiationSet& aInstantiations) const +ContentTagTestNode::FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const { nsresult rv; @@ -3737,7 +3930,7 @@ nsXULTemplateBuilder::Propogate(nsIRDFResource* aSource, InstantiationSet instantiations; instantiations.Append(seed); - rv = rdftestnode->Constrain(instantiations); + rv = rdftestnode->Constrain(instantiations, &mConflictSet); if (NS_FAILED(rv)) return rv; if (! instantiations.Empty()) { @@ -3883,7 +4076,7 @@ nsXULTemplateBuilder::Retract(nsIRDFResource* aSource, MatchSet firings; MatchSet retractions; - rdftestnode->Retract(mConflictSet, aSource, aProperty, aTarget, firings, retractions); + rdftestnode->Retract(aSource, aProperty, aTarget, firings, retractions); { MatchSet::Iterator last = retractions.Last(); @@ -5623,7 +5816,7 @@ nsXULTemplateBuilder::Log(const char* aOperation, //---------------------------------------------------------------------- nsresult -nsXULTemplateBuilder::ContentIdTestNode::FilterInstantiations(InstantiationSet& aInstantiations) const +nsXULTemplateBuilder::ContentIdTestNode::FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const { nsresult rv; @@ -5645,7 +5838,13 @@ nsXULTemplateBuilder::ContentIdTestNode::FilterInstantiations(InstantiationSet& gXULUtils->GetElementRefResource(VALUE_TO_ICONTENT(contentValue), getter_AddRefs(resource)); if (resource.get() == VALUE_TO_IRDFRESOURCE(idValue)) { - inst->AddSupportingElement(new Element(VALUE_TO_ICONTENT(contentValue))); + Element* element = new (mConflictSet.GetPool()) + Element(VALUE_TO_ICONTENT(contentValue)); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + inst->AddSupportingElement(element); } else { aInstantiations.Erase(inst--); @@ -5660,7 +5859,15 @@ nsXULTemplateBuilder::ContentIdTestNode::FilterInstantiations(InstantiationSet& if (resource) { Instantiation newinst = *inst; newinst.AddBinding(mIdVariable, Value(resource.get())); - newinst.AddSupportingElement(new Element(VALUE_TO_ICONTENT(contentValue))); + + Element* element = new (mConflictSet.GetPool()) + Element(VALUE_TO_ICONTENT(contentValue)); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + newinst.AddSupportingElement(element); + aInstantiations.Insert(inst, newinst); } @@ -5681,13 +5888,20 @@ nsXULTemplateBuilder::ContentIdTestNode::FilterInstantiations(InstantiationSet& for (PRInt32 j = PRInt32(count) - 1; j >= 0; --j) { nsISupports* isupports = elements->ElementAt(j); - nsCOMPtr element = do_QueryInterface(isupports); + nsCOMPtr content = do_QueryInterface(isupports); NS_IF_RELEASE(isupports); - if (IsElementContainedBy(element, mRoot)) { + if (IsElementContainedBy(content, mRoot)) { Instantiation newinst = *inst; - newinst.AddBinding(mContentVariable, Value(element.get())); - newinst.AddSupportingElement(new Element(element)); + newinst.AddBinding(mContentVariable, Value(content.get())); + + Element* element = new (mConflictSet.GetPool()) Element(content); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + newinst.AddSupportingElement(element); + aInstantiations.Insert(inst, newinst); } } @@ -5799,6 +6013,7 @@ nsXULTemplateBuilder::InitializeRuleNetwork(InnerNode** aChildNode) ContentIdTestNode* idnode = new ContentIdTestNode(mRules.GetRoot(), + mConflictSet, xuldoc, mRoot, mContentVar, @@ -5813,6 +6028,7 @@ nsXULTemplateBuilder::InitializeRuleNetwork(InnerNode** aChildNode) // Create (?container ^member ?member) RDFContainerMemberTestNode* membernode = new RDFContainerMemberTestNode(idnode, + mConflictSet, mDB, mContainmentProperties, mContainerVar, @@ -6019,7 +6235,7 @@ nsXULTemplateBuilder::CompileSimpleRule(nsIContent* aRule, // JoinNode in here somewhere. nsCOMPtr tag = dont_AddRef(NS_NewAtom(value)); - testnode = new ContentTagTestNode(aParentNode, mContentVar, tag); + testnode = new ContentTagTestNode(aParentNode, mConflictSet, mContentVar, tag); if (! testnode) return NS_ERROR_OUT_OF_MEMORY; } @@ -6062,6 +6278,7 @@ nsXULTemplateBuilder::CompileSimpleRule(nsIContent* aRule, } testnode = new RDFContainerInstanceTestNode(aParentNode, + mConflictSet, mDB, mContainmentProperties, mMemberVar, @@ -6096,7 +6313,7 @@ nsXULTemplateBuilder::CompileSimpleRule(nsIContent* aRule, target = do_QueryInterface(literal); } - testnode = new RDFPropertyTestNode(aParentNode, mDB, mMemberVar, property, target); + testnode = new RDFPropertyTestNode(aParentNode, mConflictSet, mDB, mMemberVar, property, target); if (! testnode) return NS_ERROR_OUT_OF_MEMORY; @@ -6118,7 +6335,7 @@ nsXULTemplateBuilder::CompileSimpleRule(nsIContent* aRule, // The InstantiationNode owns the rule now. InstantiationNode* instnode = - new InstantiationNode(rule, &mConflictSet, mDB); + new InstantiationNode(mConflictSet, rule, mDB); if (! instnode) return NS_ERROR_OUT_OF_MEMORY; @@ -6173,7 +6390,7 @@ nsXULTemplateBuilder::CompileExtendedRule(nsIContent* aRule, // And now add the instantiation node: it owns the rule now. InstantiationNode* instnode = - new InstantiationNode(rule, &mConflictSet, mDB); + new InstantiationNode(mConflictSet, rule, mDB); if (! instnode) return NS_ERROR_OUT_OF_MEMORY; @@ -6363,13 +6580,13 @@ nsXULTemplateBuilder::CompileTripleCondition(Rule* aRule, RDFPropertyTestNode* testnode = nsnull; if (svar && ovar) { - testnode = new RDFPropertyTestNode(aParentNode, mDB, svar, pres, ovar); + testnode = new RDFPropertyTestNode(aParentNode, mConflictSet, mDB, svar, pres, ovar); } else if (svar) { - testnode = new RDFPropertyTestNode(aParentNode, mDB, svar, pres, onode); + testnode = new RDFPropertyTestNode(aParentNode, mConflictSet, mDB, svar, pres, onode); } else if (ovar) { - testnode = new RDFPropertyTestNode(aParentNode, mDB, sres, pres, ovar); + testnode = new RDFPropertyTestNode(aParentNode, mConflictSet, mDB, sres, pres, ovar); } else { PR_LOG(gLog, PR_LOG_ALWAYS, @@ -6435,6 +6652,7 @@ nsXULTemplateBuilder::CompileMemberCondition(Rule* aRule, TestNode* testnode = new RDFContainerMemberTestNode(aParentNode, + mConflictSet, mDB, mContainmentProperties, containervar, @@ -6488,6 +6706,7 @@ nsXULTemplateBuilder::CompileContentCondition(Rule* aRule, // condition. TestNode* testnode = new ContentIdTestNode(aParentNode, + mConflictSet, mDocument, mRoot, mContentVar, // XXX see above diff --git a/rdf/content/src/nsRuleNetwork.cpp b/rdf/content/src/nsRuleNetwork.cpp index ddd092e8951..2e49f19496a 100644 --- a/rdf/content/src/nsRuleNetwork.cpp +++ b/rdf/content/src/nsRuleNetwork.cpp @@ -598,7 +598,7 @@ RootNode::Propogate(const InstantiationSet& aInstantiations, void* aClosure) } nsresult -RootNode::Constrain(InstantiationSet& aInstantiations) +RootNode::Constrain(InstantiationSet& aInstantiations, void* aClosure) { return NS_OK; } @@ -676,7 +676,7 @@ JoinNode::Propogate(const InstantiationSet& aInstantiations, void* aClosure) if (! instantiations.Empty()) { // propogate consistency checking back up the tree - rv = test->Constrain(instantiations); + rv = test->Constrain(instantiations, aClosure); if (NS_FAILED(rv)) return rv; NodeSet::Iterator last = mKids.Last(); @@ -753,7 +753,7 @@ JoinNode::Bind(InstantiationSet& aInstantiations, PRBool* aDidBind) } nsresult -JoinNode::Constrain(InstantiationSet& aInstantiations) +JoinNode::Constrain(InstantiationSet& aInstantiations, void* aClosure) { if (aInstantiations.Empty()) return NS_OK; @@ -782,7 +782,7 @@ JoinNode::Constrain(InstantiationSet& aInstantiations) last = mLeftParent; } - rv = first->Constrain(aInstantiations); + rv = first->Constrain(aInstantiations, aClosure); if (NS_FAILED(rv)) return rv; if (! didBind) { @@ -792,7 +792,7 @@ JoinNode::Constrain(InstantiationSet& aInstantiations) NS_ASSERTION(didBind, "uh oh, still no binding"); } - rv = last->Constrain(aInstantiations); + rv = last->Constrain(aInstantiations, aClosure); if (NS_FAILED(rv)) return rv; if (! didBind) { @@ -865,7 +865,7 @@ TestNode::Propogate(const InstantiationSet& aInstantiations, void* aClosure) nsresult rv; InstantiationSet instantiations = aInstantiations; - rv = FilterInstantiations(instantiations); + rv = FilterInstantiations(instantiations, aClosure); if (NS_FAILED(rv)) return rv; if (! instantiations.Empty()) { @@ -879,17 +879,17 @@ TestNode::Propogate(const InstantiationSet& aInstantiations, void* aClosure) nsresult -TestNode::Constrain(InstantiationSet& aInstantiations) +TestNode::Constrain(InstantiationSet& aInstantiations, void* aClosure) { nsresult rv; - rv = FilterInstantiations(aInstantiations); + rv = FilterInstantiations(aInstantiations, aClosure); if (NS_FAILED(rv)) return rv; if (! aInstantiations.Empty()) { // if we still have instantiations, then ride 'em on up to the // parent to narrow them. - rv = mParent->Constrain(aInstantiations); + rv = mParent->Constrain(aInstantiations, aClosure); } else { rv = NS_OK; diff --git a/rdf/content/src/nsRuleNetwork.h b/rdf/content/src/nsRuleNetwork.h index 4c667869d5e..decb6a046a4 100644 --- a/rdf/content/src/nsRuleNetwork.h +++ b/rdf/content/src/nsRuleNetwork.h @@ -137,7 +137,7 @@ public: virtual const char* Type() const = 0; virtual PLHashNumber Hash() const = 0; virtual PRBool Equals(const MemoryElement& aElement) const = 0; - virtual MemoryElement* Clone() const = 0; + virtual MemoryElement* Clone(void* aPool) const = 0; PRBool operator==(const MemoryElement& aMemoryElement) const { return Equals(aMemoryElement); @@ -719,7 +719,7 @@ class InnerNode : public ReteNode { public: // "upward" propogations - virtual nsresult Constrain(InstantiationSet& aInstantiations) = 0; + virtual nsresult Constrain(InstantiationSet& aInstantiations, void* aClosure) = 0; virtual nsresult GetAncestorVariables(VariableSet& aVariables) const = 0; @@ -744,7 +744,7 @@ public: virtual nsresult Propogate(const InstantiationSet& aInstantiations, void* aClosure); // "upward" propogations - virtual nsresult Constrain(InstantiationSet& aInstantiations); + virtual nsresult Constrain(InstantiationSet& aInstantiations, void* aClosure); virtual nsresult GetAncestorVariables(VariableSet& aVariables) const; @@ -773,7 +773,7 @@ public: virtual nsresult Propogate(const InstantiationSet& aInstantiations, void* aClosure); // "upward" propogations - virtual nsresult Constrain(InstantiationSet& aInstantiations); + virtual nsresult Constrain(InstantiationSet& aInstantiations, void* aClosure); virtual nsresult GetAncestorVariables(VariableSet& aVariables) const; @@ -808,10 +808,10 @@ public: virtual nsresult Propogate(const InstantiationSet& aInstantiations, void* aClosure); // "upward" propogations - virtual nsresult Constrain(InstantiationSet& aInstantiations); + virtual nsresult Constrain(InstantiationSet& aInstantiations, void* aClosure); // instantiation filtering - virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations) const = 0; //XXX probably better named "ApplyConstraints" or "Discrminiate" or something + virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const = 0; //XXX probably better named "ApplyConstraints" or "Discrminiate" or something virtual nsresult GetAncestorVariables(VariableSet& aVariables) const; diff --git a/rdf/content/src/nsXULTemplateBuilder.cpp b/rdf/content/src/nsXULTemplateBuilder.cpp index 22be81db00f..033ebd314f5 100644 --- a/rdf/content/src/nsXULTemplateBuilder.cpp +++ b/rdf/content/src/nsXULTemplateBuilder.cpp @@ -44,6 +44,7 @@ #include "nsCOMPtr.h" #include "nsCRT.h" +#include "nsFixedSizeAllocator.h" #include "nsIAtom.h" #include "nsIContent.h" #include "nsIDOMElement.h" @@ -555,6 +556,12 @@ protected: PRInt32 mRefCnt; public: + static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) { + return aAllocator.Alloc(aSize); } + + static void operator delete(void* aPtr, size_t aSize) { + nsFixedSizeAllocator::Free(aPtr, aSize); } + Match(const Rule* aRule, const Instantiation& aInstantiation, nsBindingSet aBindings) : mRefCnt(1), mRule(aRule), @@ -617,6 +624,12 @@ private: protected: struct MatchList { + static void* operator new(size_t aSize, nsFixedSizeAllocator& aPool) { + return aPool.Alloc(aSize); } + + static void operator delete(void* aPtr, size_t aSize) { + nsFixedSizeAllocator::Free(aPtr, aSize); } + Match* mMatch; MatchList* mNext; MatchList* mPrev; @@ -624,7 +637,7 @@ protected: MatchList mHead; - // XXXwaterson Lazily create this if we pass a size threshold. + // Lazily created when we pass a size threshold. PLHashTable* mMatches; PRInt32 mCount; @@ -641,7 +654,31 @@ protected: enum { kHashTableThreshold = 8 }; + static PLHashAllocOps gAllocOps; + + static void* PR_CALLBACK AllocTable(void* aPool, PRSize aSize) { + return new char[aSize]; } + + static void PR_CALLBACK FreeTable(void* aPool, void* aItem) { + delete[] NS_STATIC_CAST(char*, aItem); } + + static PLHashEntry* PR_CALLBACK AllocEntry(void* aPool, const void* aKey) { + nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool); + PLHashEntry* entry = NS_STATIC_CAST(PLHashEntry*, pool->Alloc(sizeof(PLHashEntry))); + return entry; } + + static void PR_CALLBACK FreeEntry(void* aPool, PLHashEntry* aEntry, PRUintn aFlag) { + if (aFlag == HT_FREE_ENTRY) + nsFixedSizeAllocator::Free(aEntry, sizeof(PLHashEntry)); } + public: + // Used to initialize the nsFixedSizeAllocator that's used to pool + // entries. + enum { + kEntrySize = sizeof(MatchList), + kIndexSize = sizeof(PLHashEntry) + }; + class ConstIterator { protected: friend class Iterator; // XXXwaterson so broken. @@ -740,16 +777,18 @@ public: const Match* GetLastMatch() const { return mLastMatch; } void SetLastMatch(const Match* aMatch) { mLastMatch = aMatch; } - Iterator Insert(Iterator aIterator, Match* aMatch); + Iterator Insert(nsFixedSizeAllocator& aPool, Iterator aIterator, Match* aMatch); - Iterator Add(Match* aMatch) { - return Insert(Last(), aMatch); } + Iterator Add(nsFixedSizeAllocator& aPool, Match* aMatch) { + return Insert(aPool, Last(), aMatch); } void Clear(); Iterator Erase(Iterator aIterator); }; +PLHashAllocOps MatchSet::gAllocOps = { + AllocTable, FreeTable, AllocEntry, FreeEntry }; MatchSet::MatchSet() @@ -777,7 +816,7 @@ MatchSet::~MatchSet() MatchSet::Iterator -MatchSet::Insert(Iterator aIterator, Match* aMatch) +MatchSet::Insert(nsFixedSizeAllocator& aPool, Iterator aIterator, Match* aMatch) { if (++mCount > kHashTableThreshold && !mMatches) { // If we've exceeded a high-water mark, then hash everything. @@ -785,8 +824,8 @@ MatchSet::Insert(Iterator aIterator, Match* aMatch) HashMatch, CompareMatches, PL_CompareValues, - nsnull /* XXXwaterson use an arena */, - nsnull); + &gAllocOps, + &aPool); Iterator last = Last(); for (Iterator match = First(); match != last; ++match) { @@ -800,7 +839,7 @@ MatchSet::Insert(Iterator aIterator, Match* aMatch) } } - MatchList* newelement = new MatchList(); + MatchList* newelement = new (aPool) MatchList(); if (newelement) { newelement->mMatch = aMatch; aMatch->AddRef(); @@ -996,6 +1035,8 @@ protected: PLHashTable* mTable; Entry mHead; + nsFixedSizeAllocator mPool; + public: KeySet(); ~KeySet(); @@ -1045,53 +1086,56 @@ public: protected: static PLHashAllocOps gAllocOps; - static void* PR_CALLBACK AllocTable(void* aPool, PRSize aSize); - static void PR_CALLBACK FreeTable(void* aPool, void* aItem); - static PLHashEntry* PR_CALLBACK AllocEntry(void* aPool, const void* aKey); - static void PR_CALLBACK FreeEntry(void* aPool, PLHashEntry* aEntry, PRUintn aFlag); + static void* PR_CALLBACK AllocTable(void* aPool, PRSize aSize) { + return new char[aSize]; } + + static void PR_CALLBACK FreeTable(void* aPool, void* aItem) { + delete[] NS_STATIC_CAST(char*, aItem); } + + static PLHashEntry* PR_CALLBACK AllocEntry(void* aPool, const void* aKey) { + nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool); + const Key* key = NS_STATIC_CAST(const Key*, aKey); + + Entry* entry = NS_STATIC_CAST(Entry*, pool->Alloc(sizeof(Entry))); + if (! entry) + return nsnull; + + // Need to explicitly call ctor + entry->Entry::Entry(*key); + + return NS_REINTERPRET_CAST(PLHashEntry*, entry); } + + static void PR_CALLBACK FreeEntry(void* aPool, PLHashEntry* aEntry, PRUintn aFlag) { + if (aFlag == HT_FREE_ENTRY) { + Entry* entry = NS_REINTERPRET_CAST(Entry*, aEntry); + + // Need to explicitly call dtor + entry->Entry::~Entry(); + + nsFixedSizeAllocator::Free(entry, sizeof(Entry)); + } } }; PLHashAllocOps KeySet::gAllocOps = { - AllocTable, - FreeTable, - AllocEntry, - FreeEntry -}; + AllocTable, FreeTable, AllocEntry, FreeEntry }; -void* PR_CALLBACK -KeySet::AllocTable(void* aPool, PRSize aSize) -{ - return new char[aSize]; -} - -void PR_CALLBACK -KeySet::FreeTable(void* aPool, void* aItem) -{ - delete[] NS_STATIC_CAST(char*, aItem); -} - -PLHashEntry* PR_CALLBACK -KeySet::AllocEntry(void* aPool, const void* aKey) -{ - const Key* key = NS_STATIC_CAST(const Key*, aKey); - Entry* entry = new Entry(*key); - return NS_REINTERPRET_CAST(PLHashEntry*, entry); -} - -void PR_CALLBACK -KeySet::FreeEntry(void* aPool, PLHashEntry* aEntry, PRUintn aFlag) -{ - Entry* entry = NS_REINTERPRET_CAST(Entry*, aEntry); - delete entry; -} KeySet::KeySet() : mTable(nsnull) { mHead.mPrev = mHead.mNext = &mHead; - mTable = PL_NewHashTable(8, Key::HashKey, Key::CompareKeys, PL_CompareValues, - &gAllocOps, nsnull); + static const size_t kBucketSizes[] = { sizeof(Entry) }; + static const PRInt32 kNumBuckets = sizeof(kBucketSizes) / sizeof(size_t); + static const PRInt32 kInitialEntries = 8; + + static const PRInt32 kInitialPoolSize = + NS_SIZE_IN_HEAP(sizeof(Entry)) * kInitialEntries; + + mPool.Init("KeySet", kBucketSizes, kNumBuckets, kInitialPoolSize); + + mTable = PL_NewHashTable(kInitialEntries, Key::HashKey, Key::CompareKeys, + PL_CompareValues, &gAllocOps, &mPool); MOZ_COUNT_CTOR(KeySet); } @@ -1161,6 +1205,8 @@ public: void Clear(); + nsFixedSizeAllocator& GetPool() { return mPool; } + protected: nsresult Init(); nsresult Destroy(); @@ -1179,10 +1225,35 @@ protected: }; static PLHashAllocOps gMatchAllocOps; - static void* PR_CALLBACK AllocMatchTable(void* aPool, PRSize aSize); - static void PR_CALLBACK FreeMatchTable(void* aPool, void* aItem); - static PLHashEntry* PR_CALLBACK AllocMatchEntry(void* aPool, const void* aKey); - static void PR_CALLBACK FreeMatchEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag); + + static void* PR_CALLBACK AllocMatchTable(void* aPool, PRSize aSize) { + return new char[aSize]; } + + static void PR_CALLBACK FreeMatchTable(void* aPool, void* aItem) { + delete[] NS_STATIC_CAST(char*, aItem); } + + static PLHashEntry* PR_CALLBACK AllocMatchEntry(void* aPool, const void* aKey) { + nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool); + + MatchEntry* entry = NS_STATIC_CAST(MatchEntry*, pool->Alloc(sizeof(MatchEntry))); + if (! entry) + return nsnull; + + // Need to explicitly call ctor + entry->MatchEntry::MatchEntry(); + + entry->mKey = *NS_STATIC_CAST(const Key*, aKey); + return NS_REINTERPRET_CAST(PLHashEntry*, entry); } + + static void PR_CALLBACK FreeMatchEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag) { + if (aFlag == HT_FREE_ENTRY) { + MatchEntry* entry = NS_REINTERPRET_CAST(MatchEntry*, aHashEntry); + + // Need to explicitly call dtor + entry->MatchEntry::~MatchEntry(); + + nsFixedSizeAllocator::Free(entry, sizeof(MatchEntry)); + } } // Maps a MemoryElement to the matches that it supports PLHashTable* mSupport; @@ -1201,11 +1272,39 @@ protected: MatchSet mMatchSet; }; - static PLHashAllocOps gBindingAllocOps; - static void* PR_CALLBACK AllocSupportTable(void* aPool, PRSize aSize); - static void PR_CALLBACK FreeSupportTable(void* aPool, void* aItem); - static PLHashEntry* PR_CALLBACK AllocSupportEntry(void* aPool, const void* aKey); - static void PR_CALLBACK FreeSupportEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag); + static PLHashAllocOps gSupportAllocOps; + + static void* PR_CALLBACK AllocSupportTable(void* aPool, PRSize aSize) { + return new char[aSize]; } + + static void PR_CALLBACK FreeSupportTable(void* aPool, void* aItem) { + delete[] NS_STATIC_CAST(char*, aItem); } + + static PLHashEntry* PR_CALLBACK AllocSupportEntry(void* aPool, const void* aKey) { + nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool); + + SupportEntry* entry = NS_STATIC_CAST(SupportEntry*, pool->Alloc(sizeof(SupportEntry))); + if (! entry) + return nsnull; + + // Need to explicitly call ctor + entry->SupportEntry::SupportEntry(); + + const MemoryElement* element = NS_STATIC_CAST(const MemoryElement*, aKey); + entry->mElement = element->Clone(aPool); + + return NS_REINTERPRET_CAST(PLHashEntry*, entry); } + + static void PR_CALLBACK FreeSupportEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag) { + if (aFlag == HT_FREE_ENTRY) { + SupportEntry* entry = NS_REINTERPRET_CAST(SupportEntry*, aHashEntry); + + // Need to explicitly call dtor + entry->SupportEntry::~SupportEntry(); + + nsFixedSizeAllocator::Free(entry, sizeof(SupportEntry)); + } } + static PLHashNumber HashMemoryElement(const void* aBinding); static PRIntn CompareMemoryElements(const void* aLeft, const void* aRight); @@ -1232,91 +1331,45 @@ protected: static PLHashEntry* PR_CALLBACK AllocResourceEntry(void* aPool, const void* aKey) { - ResourceEntry* entry = new ResourceEntry; + nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool); + + ResourceEntry* entry = + NS_STATIC_CAST(ResourceEntry*, pool->Alloc(sizeof(ResourceEntry))); + + if (! entry) + return nsnull; + + // Need to explicitly call ctor + entry->ResourceEntry::ResourceEntry(); + return NS_REINTERPRET_CAST(PLHashEntry*, entry); } static void PR_CALLBACK FreeResourceEntry(void* aPool, PLHashEntry* aEntry, PRUintn aFlag) { - delete NS_REINTERPRET_CAST(ResourceEntry*, aEntry); } + if (aFlag == HT_FREE_ENTRY) { + ResourceEntry* entry = NS_REINTERPRET_CAST(ResourceEntry*, aEntry); + + // Need to explicitly call dtor + entry->ResourceEntry::~ResourceEntry(); + + nsFixedSizeAllocator::Free(entry, sizeof(ResourceEntry)); + } } static PLHashNumber HashPointer(const void* aKey) { return PLHashNumber(aKey) >> 3; } + + nsFixedSizeAllocator mPool; }; // Allocation operations for the match table PLHashAllocOps ConflictSet::gMatchAllocOps = { AllocMatchTable, FreeMatchTable, AllocMatchEntry, FreeMatchEntry }; - -void* PR_CALLBACK -ConflictSet::AllocMatchTable(void* aPool, PRSize aSize) -{ - return new char[aSize]; -} - -void PR_CALLBACK -ConflictSet::FreeMatchTable(void* aPool, void* aItem) -{ - delete[] NS_STATIC_CAST(char*, aItem); -} - -PLHashEntry* PR_CALLBACK -ConflictSet::AllocMatchEntry(void* aPool, const void* aKey) -{ - MatchEntry* entry = new MatchEntry(); - if (! entry) - return nsnull; - - entry->mKey = *NS_STATIC_CAST(const Key*, aKey); - return NS_REINTERPRET_CAST(PLHashEntry*, entry); -} - -void PR_CALLBACK -ConflictSet::FreeMatchEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag) -{ - MatchEntry* entry = NS_REINTERPRET_CAST(MatchEntry*, aHashEntry); - delete entry; -} - // Allocation operations for the bindings table -PLHashAllocOps ConflictSet::gBindingAllocOps = { +PLHashAllocOps ConflictSet::gSupportAllocOps = { AllocSupportTable, FreeSupportTable, AllocSupportEntry, FreeSupportEntry }; - -void* PR_CALLBACK -ConflictSet::AllocSupportTable(void* aPool, PRSize aSize) -{ - return new char[aSize]; -} - -void PR_CALLBACK -ConflictSet::FreeSupportTable(void* aPool, void* aItem) -{ - delete[] NS_STATIC_CAST(char*, aItem); -} - -PLHashEntry* PR_CALLBACK -ConflictSet::AllocSupportEntry(void* aPool, const void* aKey) -{ - SupportEntry* entry = new SupportEntry(); - if (! entry) - return nsnull; - - const MemoryElement* element = NS_STATIC_CAST(const MemoryElement*, aKey); - entry->mElement = element->Clone(); - - return NS_REINTERPRET_CAST(PLHashEntry*, entry); -} - -void PR_CALLBACK -ConflictSet::FreeSupportEntry(void* aPool, PLHashEntry* aHashEntry, PRUintn aFlag) -{ - SupportEntry* entry = NS_REINTERPRET_CAST(SupportEntry*, aHashEntry); - delete entry; -} - - ConflictSet::ConflictSet() : mMatches(nsnull), mSupport(nsnull) { @@ -1332,26 +1385,48 @@ ConflictSet::~ConflictSet() nsresult ConflictSet::Init() { - mMatches = PL_NewHashTable(16 /* XXXwaterson we need a way to give a hint? */, + static const size_t kBucketSizes[] = { + sizeof(MatchEntry), + sizeof(SupportEntry), + sizeof(ResourceEntry), + MatchSet::kEntrySize, + MatchSet::kIndexSize + }; + + static const PRInt32 kNumBuckets = sizeof(kBucketSizes) / sizeof(size_t); + + static const PRInt32 kNumResourceElements = 64; + + static const PRInt32 kInitialSize = + (NS_SIZE_IN_HEAP(sizeof(MatchEntry)) + + NS_SIZE_IN_HEAP(sizeof(SupportEntry)) + + NS_SIZE_IN_HEAP(sizeof(ResourceEntry))) * kNumResourceElements + + (NS_SIZE_IN_HEAP(MatchSet::kEntrySize) + + NS_SIZE_IN_HEAP(MatchSet::kIndexSize)) * kNumResourceElements; + + mPool.Init("ConflictSet", kBucketSizes, kNumBuckets, kInitialSize); + + mMatches = PL_NewHashTable(kNumResourceElements /* XXXwaterson we need a way to give a hint? */, Key::HashKey, Key::CompareKeys, PL_CompareValues, &gMatchAllocOps, - nsnull /* XXXwaterson use an arena */); + &mPool); - mSupport = PL_NewHashTable(16, /* XXXwaterson need hint */ + mSupport = PL_NewHashTable(kNumResourceElements, /* XXXwaterson need hint */ HashMemoryElement, CompareMemoryElements, PL_CompareValues, - &gBindingAllocOps, - nsnull /* XXXwaterson use an arena */); + &gSupportAllocOps, + &mPool); - mResources = PL_NewHashTable(16 /* XXX arbitrary */, + mResources = PL_NewHashTable(kNumResourceElements /* XXX arbitrary */, HashPointer, PL_CompareValues, PL_CompareValues, &gResourceAllocOps, - nsnull /* XXX use an arena! */); + &mPool); + return NS_OK; } @@ -1400,7 +1475,7 @@ ConflictSet::Add(Match* aMatch, PRBool* aDidAddKey) } if (! set->Contains(*aMatch)) { - set->Add(aMatch); + set->Add(mPool, aMatch); *aDidAddKey = PR_TRUE; } } @@ -1433,7 +1508,7 @@ ConflictSet::Add(Match* aMatch, PRBool* aDidAddKey) } if (! set->Contains(*aMatch)) { - set->Add(aMatch); + set->Add(mPool, aMatch); } } } @@ -1471,7 +1546,7 @@ ConflictSet::Add(Match* aMatch, PRBool* aDidAddKey) set = &entry->mMatches; } - set->Add(aMatch); + set->Add(mPool, aMatch); } } @@ -1514,7 +1589,7 @@ ConflictSet::Remove(const MemoryElement& aMemoryElement, // instantiation we're to remove. for (MatchSet::Iterator match = set->First(); match != set->Last(); ++match) { // Note the retraction - aRetractedMatches.Add(match.operator->()); + aRetractedMatches.Add(mPool, match.operator->()); } // We'll eagerly remove it from the table. @@ -1545,7 +1620,7 @@ ConflictSet::Remove(const MemoryElement& aMemoryElement, set->FindMatchWithHighestPriority(); if (newmatch) - aNewMatches.Add(newmatch); + aNewMatches.Add(mPool, newmatch); break; } @@ -1600,11 +1675,11 @@ PLHashAllocOps ConflictSet::gResourceAllocOps = { class InstantiationNode : public ReteNode { public: - InstantiationNode(Rule* aRule, - ConflictSet* aConflictSet, + InstantiationNode(ConflictSet& aConflictSet, + Rule* aRule, nsIRDFDataSource* aDataSource) - : mRule(aRule), - mConflictSet(aConflictSet) {} + : mConflictSet(aConflictSet), + mRule(aRule) {} ~InstantiationNode(); @@ -1613,7 +1688,7 @@ public: protected: Rule* mRule; - ConflictSet* mConflictSet; + ConflictSet& mConflictSet; }; @@ -1637,12 +1712,12 @@ InstantiationNode::Propogate(const InstantiationSet& aInstantiations, void* aClo mRule->ComputeBindings(bindings); - Match* match = new Match(mRule, *inst, bindings); + Match* match = new (mConflictSet.GetPool()) Match(mRule, *inst, bindings); if (! match) return NS_ERROR_OUT_OF_MEMORY; PRBool didAddKey; - mConflictSet->Add(match, &didAddKey); + mConflictSet.Add(match, &didAddKey); match->Release(); @@ -1686,8 +1761,7 @@ public: /** * */ - virtual void Retract(ConflictSet& aConflictSet, - nsIRDFResource* aSource, + virtual void Retract(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget, MatchSet& aFirings, @@ -1721,6 +1795,7 @@ public: protected: PLHashTable* mMap; + nsFixedSizeAllocator mPool; struct Entry { PLHashEntry mHashEntry; @@ -1739,14 +1814,24 @@ protected: static PLHashEntry* PR_CALLBACK AllocEntry(void* aPool, const void* aKey) { - Entry* entry = new Entry; + nsFixedSizeAllocator* pool = NS_STATIC_CAST(nsFixedSizeAllocator*, aPool); + + Entry* entry = NS_STATIC_CAST(Entry*, pool->Alloc(sizeof(Entry))); + if (! entry) + return nsnull; + return NS_REINTERPRET_CAST(PLHashEntry*, entry); } static void PR_CALLBACK FreeEntry(void* aPool, PLHashEntry* aEntry, PRUintn aFlag) { - Entry* entry = NS_REINTERPRET_CAST(Entry*, aEntry); - entry->mMatch->Release(); - delete entry; } + if (aFlag == HT_FREE_ENTRY) { + Entry* entry = NS_REINTERPRET_CAST(Entry*, aEntry); + + if (entry->mMatch) + entry->mMatch->Release(); + + nsFixedSizeAllocator::Free(entry, sizeof(Entry)); + } } static PLHashNumber HashPointer(const void* aKey) { @@ -1758,12 +1843,22 @@ PLHashAllocOps ContentSupportMap::gAllocOps = { ContentSupportMap::ContentSupportMap() { - mMap = PL_NewHashTable(16 /* XXX arbitrary */, + static const size_t kBucketSizes[] = { sizeof(Entry) }; + static const PRInt32 kNumBuckets = sizeof(kBucketSizes) / sizeof(size_t); + + static const kInitialEntries = 16; // XXX arbitrary + + static const kInitialSize = + NS_SIZE_IN_HEAP(sizeof(Entry)) * kInitialEntries; + + mPool.Init("ContentSupportMap", kBucketSizes, kNumBuckets, kInitialSize); + + mMap = PL_NewHashTable(kInitialEntries, HashPointer, PL_CompareValues, PL_CompareValues, &gAllocOps, - nsnull /* XXX use an arena! */); + &mPool); } @@ -2106,22 +2201,30 @@ protected: { public: ContentIdTestNode(InnerNode* aParent, + ConflictSet& aConflictSet, nsIXULDocument* aDocument, nsIContent* aRoot, PRInt32 aContentVariable, PRInt32 aIdVariable) : TestNode(aParent), + mConflictSet(aConflictSet), mDocument(aDocument), mRoot(aRoot), mContentVariable(aContentVariable), mIdVariable(aIdVariable) {} - virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations) const; + virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const; virtual nsresult GetAncestorVariables(VariableSet& aVariables) const; class Element : public MemoryElement { public: + static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) { + return aAllocator.Alloc(aSize); } + + static void operator delete(void* aPtr, size_t aSize) { + nsFixedSizeAllocator::Free(aPtr, aSize); } + Element(nsIContent* aContent) : mContent(aContent) { MOZ_COUNT_CTOR(ContentIdTestNode::Element); } @@ -2141,14 +2244,16 @@ protected: } return PR_FALSE; } - virtual MemoryElement* Clone() const { - return new Element(mContent); } + virtual MemoryElement* Clone(void* aPool) const { + return new (*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool)) + Element(mContent); } protected: nsCOMPtr mContent; }; protected: + ConflictSet& mConflictSet; nsIXULDocument* mDocument; // [WEAK] because we know the document will outlive us nsCOMPtr mRoot; PRInt32 mContentVariable; @@ -2192,11 +2297,13 @@ class RDFPropertyTestNode : public RDFTestNode public: // Both source and target unbound (?source ^property ?target) RDFPropertyTestNode(InnerNode* aParent, + ConflictSet& aConflictSet, nsIRDFDataSource* aDataSource, PRInt32 aSourceVariable, nsIRDFResource* aProperty, PRInt32 aTargetVariable) : RDFTestNode(aParent), + mConflictSet(aConflictSet), mDataSource(aDataSource), mSourceVariable(aSourceVariable), mSource(nsnull), @@ -2206,11 +2313,13 @@ public: // Source bound, target unbound (source ^property ?target) RDFPropertyTestNode(InnerNode* aParent, + ConflictSet& aConflictSet, nsIRDFDataSource* aDataSource, nsIRDFResource* aSource, nsIRDFResource* aProperty, PRInt32 aTargetVariable) : RDFTestNode(aParent), + mConflictSet(aConflictSet), mDataSource(aDataSource), mSourceVariable(0), mSource(aSource), @@ -2220,11 +2329,13 @@ public: // Source unbound, target bound (?source ^property target) RDFPropertyTestNode(InnerNode* aParent, + ConflictSet& aConflictSet, nsIRDFDataSource* aDataSource, PRInt32 aSourceVariable, nsIRDFResource* aProperty, nsIRDFNode* aTarget) : RDFTestNode(aParent), + mConflictSet(aConflictSet), mDataSource(aDataSource), mSourceVariable(aSourceVariable), mSource(nsnull), @@ -2232,7 +2343,7 @@ public: mTargetVariable(0), mTarget(aTarget) {} - virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations) const; + virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const; virtual nsresult GetAncestorVariables(VariableSet& aVariables) const; @@ -2243,8 +2354,7 @@ public: Instantiation& aInitialBindings) const; virtual void - Retract(ConflictSet& aConflictSet, - nsIRDFResource* aSource, + Retract(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget, MatchSet& aFirings, @@ -2253,6 +2363,12 @@ public: class Element : public MemoryElement { public: + static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) { + return aAllocator.Alloc(aSize); } + + static void operator delete(void* aPtr, size_t aSize) { + nsFixedSizeAllocator::Free(aPtr, aSize); } + Element(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget) @@ -2280,8 +2396,9 @@ public: } return PR_FALSE; } - virtual MemoryElement* Clone() const { - return new Element(mSource, mProperty, mTarget); } + virtual MemoryElement* Clone(void* aPool) const { + return new (*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool)) + Element(mSource, mProperty, mTarget); } protected: nsCOMPtr mSource; @@ -2290,6 +2407,7 @@ public: }; protected: + ConflictSet& mConflictSet; nsCOMPtr mDataSource; PRInt32 mSourceVariable; nsCOMPtr mSource; @@ -2300,7 +2418,7 @@ protected: nsresult -RDFPropertyTestNode::FilterInstantiations(InstantiationSet& aInstantiations) const +RDFPropertyTestNode::FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const { nsresult rv; @@ -2340,9 +2458,15 @@ RDFPropertyTestNode::FilterInstantiations(InstantiationSet& aInstantiations) con if (hasAssertion) { // it's consistent. - inst->AddSupportingElement(new Element(VALUE_TO_IRDFRESOURCE(sourceValue), - mProperty, - VALUE_TO_IRDFNODE(targetValue))); + Element* element = new (mConflictSet.GetPool()) + Element(VALUE_TO_IRDFRESOURCE(sourceValue), + mProperty, + VALUE_TO_IRDFNODE(targetValue)); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + inst->AddSupportingElement(element); } else { // it's inconsistent. remove it. @@ -2408,9 +2532,17 @@ RDFPropertyTestNode::FilterInstantiations(InstantiationSet& aInstantiations) con // introduced. Ownership will be transferred to the Instantiation newinst = *inst; newinst.AddBinding(variable, value); - newinst.AddSupportingElement(new Element(VALUE_TO_IRDFRESOURCE(sourceValue), - mProperty, - VALUE_TO_IRDFNODE(targetValue))); + + Element* element = new (mConflictSet.GetPool()) + Element(VALUE_TO_IRDFRESOURCE(sourceValue), + mProperty, + VALUE_TO_IRDFNODE(targetValue)); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + newinst.AddSupportingElement(element); + aInstantiations.Insert(inst, newinst); } @@ -2470,15 +2602,14 @@ RDFPropertyTestNode::CanPropogate(nsIRDFResource* aSource, } void -RDFPropertyTestNode::Retract(ConflictSet& aConflictSet, - nsIRDFResource* aSource, +RDFPropertyTestNode::Retract(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget, MatchSet& aFirings, MatchSet& aRetractions) const { if (aProperty == mProperty.get()) { - aConflictSet.Remove(Element(aSource, aProperty, aTarget), aFirings, aRetractions); + mConflictSet.Remove(Element(aSource, aProperty, aTarget), aFirings, aRetractions); } } @@ -2489,17 +2620,19 @@ class RDFContainerMemberTestNode : public RDFTestNode { public: RDFContainerMemberTestNode(InnerNode* aParent, + ConflictSet& aConflictSet, nsIRDFDataSource* aDataSource, const PropertySet& aMembershipProperties, PRInt32 aContainerVariable, PRInt32 aMemberVariable) : RDFTestNode(aParent), + mConflictSet(aConflictSet), mDataSource(aDataSource), mMembershipProperties(aMembershipProperties), mContainerVariable(aContainerVariable), mMemberVariable(aMemberVariable) {} - virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations) const; + virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const; virtual nsresult GetAncestorVariables(VariableSet& aVariables) const; @@ -2510,8 +2643,7 @@ public: Instantiation& aInitialBindings) const; virtual void - Retract(ConflictSet& aConflictSet, - nsIRDFResource* aSource, + Retract(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget, MatchSet& aFirings, @@ -2519,6 +2651,12 @@ public: class Element : public MemoryElement { public: + static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) { + return aAllocator.Alloc(aSize); } + + static void operator delete(void* aPtr, size_t aSize) { + nsFixedSizeAllocator::Free(aPtr, aSize); } + Element(nsIRDFResource* aContainer, nsIRDFNode* aMember) : mContainer(aContainer), @@ -2541,8 +2679,9 @@ public: } return PR_FALSE; } - virtual MemoryElement* Clone() const { - return new Element(mContainer, mMember); } + virtual MemoryElement* Clone(void* aPool) const { + return new (*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool)) + Element(mContainer, mMember); } protected: nsCOMPtr mContainer; @@ -2550,6 +2689,7 @@ public: }; protected: + ConflictSet& mConflictSet; nsCOMPtr mDataSource; const PropertySet& mMembershipProperties; PRInt32 mContainerVariable; @@ -2557,7 +2697,7 @@ protected: }; nsresult -RDFContainerMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiations) const +RDFContainerMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const { // XXX Uh, factor me, please! nsresult rv; @@ -2637,8 +2777,14 @@ RDFContainerMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiatio if (isconsistent) { // Add a memory element to our set-of-support. - inst->AddSupportingElement(new Element(VALUE_TO_IRDFRESOURCE(containerValue), - VALUE_TO_IRDFNODE(memberValue))); + Element* element = new (mConflictSet.GetPool()) + Element(VALUE_TO_IRDFRESOURCE(containerValue), + VALUE_TO_IRDFNODE(memberValue)); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + inst->AddSupportingElement(element); } else { // it's inconsistent. remove it. @@ -2675,8 +2821,15 @@ RDFContainerMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiatio Instantiation newinst = *inst; newinst.AddBinding(mMemberVariable, Value(node.get())); - newinst.AddSupportingElement(new Element(VALUE_TO_IRDFRESOURCE(containerValue), - node)); + + Element* element = new (mConflictSet.GetPool()) + Element(VALUE_TO_IRDFRESOURCE(containerValue), node); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + newinst.AddSupportingElement(element); + aInstantiations.Insert(inst, newinst); } } @@ -2749,7 +2902,15 @@ RDFContainerMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiatio // Add a new instantiation Instantiation newinst = *inst; newinst.AddBinding(mContainerVariable, Value(source.get())); - newinst.AddSupportingElement(new Element(source, VALUE_TO_IRDFNODE(memberValue))); + + Element* element = new (mConflictSet.GetPool()) + Element(source, VALUE_TO_IRDFNODE(memberValue)); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + newinst.AddSupportingElement(element); + aInstantiations.Insert(inst, newinst); } } @@ -2814,14 +2975,24 @@ RDFContainerMemberTestNode::FilterInstantiations(InstantiationSet& aInstantiatio // introduced. Ownership will be transferred to the Instantiation newinst = *inst; newinst.AddBinding(variable, value); + + Element* element; if (hasContainerBinding) { - newinst.AddSupportingElement(new Element(VALUE_TO_IRDFRESOURCE(containerValue), - VALUE_TO_IRDFNODE(value))); + element = new (mConflictSet.GetPool()) + Element(VALUE_TO_IRDFRESOURCE(containerValue), + VALUE_TO_IRDFNODE(value)); } else { - newinst.AddSupportingElement(new Element(VALUE_TO_IRDFRESOURCE(value), - VALUE_TO_IRDFNODE(memberValue))); + element = new (mConflictSet.GetPool()) + Element(VALUE_TO_IRDFRESOURCE(value), + VALUE_TO_IRDFNODE(memberValue)); } + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + newinst.AddSupportingElement(element); + aInstantiations.Insert(inst, newinst); } } @@ -2883,8 +3054,7 @@ RDFContainerMemberTestNode::CanPropogate(nsIRDFResource* aSource, } void -RDFContainerMemberTestNode::Retract(ConflictSet& aConflictSet, - nsIRDFResource* aSource, +RDFContainerMemberTestNode::Retract(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget, MatchSet& aFirings, @@ -2902,7 +3072,7 @@ RDFContainerMemberTestNode::Retract(ConflictSet& aConflictSet, } if (canretract) { - aConflictSet.Remove(Element(aSource, aTarget), aFirings, aRetractions); + mConflictSet.Remove(Element(aSource, aTarget), aFirings, aRetractions); } } @@ -2914,19 +3084,21 @@ public: enum Test { eFalse, eTrue, eDontCare }; RDFContainerInstanceTestNode(InnerNode* aParent, + ConflictSet& aConflictSet, nsIRDFDataSource* aDataSource, const PropertySet& aMembershipProperties, PRInt32 aContainerVariable, Test aContainer, Test aEmpty) : RDFTestNode(aParent), + mConflictSet(aConflictSet), mDataSource(aDataSource), mMembershipProperties(aMembershipProperties), mContainerVariable(aContainerVariable), mContainer(aContainer), mEmpty(aEmpty) {} - virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations) const; + virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const; virtual nsresult GetAncestorVariables(VariableSet& aVariables) const; @@ -2937,8 +3109,7 @@ public: Instantiation& aInitialBindings) const; virtual void - Retract(ConflictSet& aConflictSet, - nsIRDFResource* aSource, + Retract(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget, MatchSet& aFirings, @@ -2947,6 +3118,12 @@ public: class Element : public MemoryElement { public: + static void* operator new(size_t aSize, nsFixedSizeAllocator& aAllocator) { + return aAllocator.Alloc(aSize); } + + static void operator delete(void* aPtr, size_t aSize) { + nsFixedSizeAllocator::Free(aPtr, aSize); } + Element(nsIRDFResource* aContainer, Test aContainerTest, Test aEmptyTest) @@ -2974,8 +3151,9 @@ public: } return PR_FALSE; } - virtual MemoryElement* Clone() const { - return new Element(mContainer, mContainerTest, mEmptyTest); } + virtual MemoryElement* Clone(void* aPool) const { + return new (*NS_STATIC_CAST(nsFixedSizeAllocator*, aPool)) + Element(mContainer, mContainerTest, mEmptyTest); } protected: nsCOMPtr mContainer; @@ -2984,6 +3162,7 @@ public: }; protected: + ConflictSet& mConflictSet; nsCOMPtr mDataSource; const PropertySet& mMembershipProperties; PRInt32 mContainerVariable; @@ -2992,7 +3171,7 @@ protected: }; nsresult -RDFContainerInstanceTestNode::FilterInstantiations(InstantiationSet& aInstantiations) const +RDFContainerInstanceTestNode::FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const { nsresult rv; @@ -3049,8 +3228,14 @@ RDFContainerInstanceTestNode::FilterInstantiations(InstantiationSet& aInstantiat } if (empty == mEmpty) { - inst->AddSupportingElement(new Element(VALUE_TO_IRDFRESOURCE(value), - mContainer, mEmpty)); + Element* element = new (mConflictSet.GetPool()) + Element(VALUE_TO_IRDFRESOURCE(value), + mContainer, mEmpty); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + inst->AddSupportingElement(element); } else { aInstantiations.Erase(inst--); @@ -3100,8 +3285,14 @@ RDFContainerInstanceTestNode::FilterInstantiations(InstantiationSet& aInstantiat } if (container == mContainer) { - inst->AddSupportingElement(new Element(VALUE_TO_IRDFRESOURCE(value), - mContainer, mEmpty)); + Element* element = new (mConflictSet.GetPool()) + Element(VALUE_TO_IRDFRESOURCE(value), mContainer, mEmpty); + + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + inst->AddSupportingElement(element); } else { aInstantiations.Erase(inst--); @@ -3150,8 +3341,7 @@ RDFContainerInstanceTestNode::CanPropogate(nsIRDFResource* aSource, } void -RDFContainerInstanceTestNode::Retract(ConflictSet& aConflictSet, - nsIRDFResource* aSource, +RDFContainerInstanceTestNode::Retract(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget, MatchSet& aFirings, @@ -3159,7 +3349,7 @@ RDFContainerInstanceTestNode::Retract(ConflictSet& aConflictSet, { // XXXwaterson oof. complicated. figure this out. if (0) { - aConflictSet.Remove(Element(aSource, mContainer, mEmpty), aFirings, aRetractions); + mConflictSet.Remove(Element(aSource, mContainer, mEmpty), aFirings, aRetractions); } } @@ -3169,23 +3359,26 @@ class ContentTagTestNode : public TestNode { public: ContentTagTestNode(InnerNode* aParent, + ConflictSet& aConflictSet, PRInt32 aContentVariable, nsIAtom* aTag) : TestNode(aParent), + mConflictSet(aConflictSet), mContentVariable(aContentVariable), mTag(aTag) {} - virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations) const; + virtual nsresult FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const; virtual nsresult GetAncestorVariables(VariableSet& aVariables) const; protected: + ConflictSet& mConflictSet; PRInt32 mContentVariable; nsCOMPtr mTag; }; nsresult -ContentTagTestNode::FilterInstantiations(InstantiationSet& aInstantiations) const +ContentTagTestNode::FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const { nsresult rv; @@ -3737,7 +3930,7 @@ nsXULTemplateBuilder::Propogate(nsIRDFResource* aSource, InstantiationSet instantiations; instantiations.Append(seed); - rv = rdftestnode->Constrain(instantiations); + rv = rdftestnode->Constrain(instantiations, &mConflictSet); if (NS_FAILED(rv)) return rv; if (! instantiations.Empty()) { @@ -3883,7 +4076,7 @@ nsXULTemplateBuilder::Retract(nsIRDFResource* aSource, MatchSet firings; MatchSet retractions; - rdftestnode->Retract(mConflictSet, aSource, aProperty, aTarget, firings, retractions); + rdftestnode->Retract(aSource, aProperty, aTarget, firings, retractions); { MatchSet::Iterator last = retractions.Last(); @@ -5623,7 +5816,7 @@ nsXULTemplateBuilder::Log(const char* aOperation, //---------------------------------------------------------------------- nsresult -nsXULTemplateBuilder::ContentIdTestNode::FilterInstantiations(InstantiationSet& aInstantiations) const +nsXULTemplateBuilder::ContentIdTestNode::FilterInstantiations(InstantiationSet& aInstantiations, void* aClosure) const { nsresult rv; @@ -5645,7 +5838,13 @@ nsXULTemplateBuilder::ContentIdTestNode::FilterInstantiations(InstantiationSet& gXULUtils->GetElementRefResource(VALUE_TO_ICONTENT(contentValue), getter_AddRefs(resource)); if (resource.get() == VALUE_TO_IRDFRESOURCE(idValue)) { - inst->AddSupportingElement(new Element(VALUE_TO_ICONTENT(contentValue))); + Element* element = new (mConflictSet.GetPool()) + Element(VALUE_TO_ICONTENT(contentValue)); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + inst->AddSupportingElement(element); } else { aInstantiations.Erase(inst--); @@ -5660,7 +5859,15 @@ nsXULTemplateBuilder::ContentIdTestNode::FilterInstantiations(InstantiationSet& if (resource) { Instantiation newinst = *inst; newinst.AddBinding(mIdVariable, Value(resource.get())); - newinst.AddSupportingElement(new Element(VALUE_TO_ICONTENT(contentValue))); + + Element* element = new (mConflictSet.GetPool()) + Element(VALUE_TO_ICONTENT(contentValue)); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + newinst.AddSupportingElement(element); + aInstantiations.Insert(inst, newinst); } @@ -5681,13 +5888,20 @@ nsXULTemplateBuilder::ContentIdTestNode::FilterInstantiations(InstantiationSet& for (PRInt32 j = PRInt32(count) - 1; j >= 0; --j) { nsISupports* isupports = elements->ElementAt(j); - nsCOMPtr element = do_QueryInterface(isupports); + nsCOMPtr content = do_QueryInterface(isupports); NS_IF_RELEASE(isupports); - if (IsElementContainedBy(element, mRoot)) { + if (IsElementContainedBy(content, mRoot)) { Instantiation newinst = *inst; - newinst.AddBinding(mContentVariable, Value(element.get())); - newinst.AddSupportingElement(new Element(element)); + newinst.AddBinding(mContentVariable, Value(content.get())); + + Element* element = new (mConflictSet.GetPool()) Element(content); + + if (! element) + return NS_ERROR_OUT_OF_MEMORY; + + newinst.AddSupportingElement(element); + aInstantiations.Insert(inst, newinst); } } @@ -5799,6 +6013,7 @@ nsXULTemplateBuilder::InitializeRuleNetwork(InnerNode** aChildNode) ContentIdTestNode* idnode = new ContentIdTestNode(mRules.GetRoot(), + mConflictSet, xuldoc, mRoot, mContentVar, @@ -5813,6 +6028,7 @@ nsXULTemplateBuilder::InitializeRuleNetwork(InnerNode** aChildNode) // Create (?container ^member ?member) RDFContainerMemberTestNode* membernode = new RDFContainerMemberTestNode(idnode, + mConflictSet, mDB, mContainmentProperties, mContainerVar, @@ -6019,7 +6235,7 @@ nsXULTemplateBuilder::CompileSimpleRule(nsIContent* aRule, // JoinNode in here somewhere. nsCOMPtr tag = dont_AddRef(NS_NewAtom(value)); - testnode = new ContentTagTestNode(aParentNode, mContentVar, tag); + testnode = new ContentTagTestNode(aParentNode, mConflictSet, mContentVar, tag); if (! testnode) return NS_ERROR_OUT_OF_MEMORY; } @@ -6062,6 +6278,7 @@ nsXULTemplateBuilder::CompileSimpleRule(nsIContent* aRule, } testnode = new RDFContainerInstanceTestNode(aParentNode, + mConflictSet, mDB, mContainmentProperties, mMemberVar, @@ -6096,7 +6313,7 @@ nsXULTemplateBuilder::CompileSimpleRule(nsIContent* aRule, target = do_QueryInterface(literal); } - testnode = new RDFPropertyTestNode(aParentNode, mDB, mMemberVar, property, target); + testnode = new RDFPropertyTestNode(aParentNode, mConflictSet, mDB, mMemberVar, property, target); if (! testnode) return NS_ERROR_OUT_OF_MEMORY; @@ -6118,7 +6335,7 @@ nsXULTemplateBuilder::CompileSimpleRule(nsIContent* aRule, // The InstantiationNode owns the rule now. InstantiationNode* instnode = - new InstantiationNode(rule, &mConflictSet, mDB); + new InstantiationNode(mConflictSet, rule, mDB); if (! instnode) return NS_ERROR_OUT_OF_MEMORY; @@ -6173,7 +6390,7 @@ nsXULTemplateBuilder::CompileExtendedRule(nsIContent* aRule, // And now add the instantiation node: it owns the rule now. InstantiationNode* instnode = - new InstantiationNode(rule, &mConflictSet, mDB); + new InstantiationNode(mConflictSet, rule, mDB); if (! instnode) return NS_ERROR_OUT_OF_MEMORY; @@ -6363,13 +6580,13 @@ nsXULTemplateBuilder::CompileTripleCondition(Rule* aRule, RDFPropertyTestNode* testnode = nsnull; if (svar && ovar) { - testnode = new RDFPropertyTestNode(aParentNode, mDB, svar, pres, ovar); + testnode = new RDFPropertyTestNode(aParentNode, mConflictSet, mDB, svar, pres, ovar); } else if (svar) { - testnode = new RDFPropertyTestNode(aParentNode, mDB, svar, pres, onode); + testnode = new RDFPropertyTestNode(aParentNode, mConflictSet, mDB, svar, pres, onode); } else if (ovar) { - testnode = new RDFPropertyTestNode(aParentNode, mDB, sres, pres, ovar); + testnode = new RDFPropertyTestNode(aParentNode, mConflictSet, mDB, sres, pres, ovar); } else { PR_LOG(gLog, PR_LOG_ALWAYS, @@ -6435,6 +6652,7 @@ nsXULTemplateBuilder::CompileMemberCondition(Rule* aRule, TestNode* testnode = new RDFContainerMemberTestNode(aParentNode, + mConflictSet, mDB, mContainmentProperties, containervar, @@ -6488,6 +6706,7 @@ nsXULTemplateBuilder::CompileContentCondition(Rule* aRule, // condition. TestNode* testnode = new ContentIdTestNode(aParentNode, + mConflictSet, mDocument, mRoot, mContentVar, // XXX see above