Bug 1027921 - Part 8: Remove dead entries. r=froydnj, r=cjones
This commit is contained in:
@@ -90,6 +90,7 @@ BlockingResourceBase::~BlockingResourceBase()
|
|||||||
// base class, or its underlying primitive, will check for such
|
// base class, or its underlying primitive, will check for such
|
||||||
// stupid mistakes.
|
// stupid mistakes.
|
||||||
mChainPrev = 0; // racy only for stupidly buggy client code
|
mChainPrev = 0; // racy only for stupidly buggy client code
|
||||||
|
sDeadlockDetector->Remove(mDDEntry);
|
||||||
mDDEntry = 0; // owned by deadlock detector
|
mDDEntry = 0; // owned by deadlock detector
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -195,6 +195,7 @@ private:
|
|||||||
OrderingEntry(const T* aResource)
|
OrderingEntry(const T* aResource)
|
||||||
: mFirstSeen(CallStack::kNone)
|
: mFirstSeen(CallStack::kNone)
|
||||||
, mOrderedLT() // FIXME bug 456272: set to empirical dep size?
|
, mOrderedLT() // FIXME bug 456272: set to empirical dep size?
|
||||||
|
, mExternalRefs()
|
||||||
, mResource(aResource)
|
, mResource(aResource)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -207,12 +208,14 @@ private:
|
|||||||
{
|
{
|
||||||
size_t n = aMallocSizeOf(this);
|
size_t n = aMallocSizeOf(this);
|
||||||
n += mOrderedLT.SizeOfExcludingThis(aMallocSizeOf);
|
n += mOrderedLT.SizeOfExcludingThis(aMallocSizeOf);
|
||||||
|
n += mExternalRefs.SizeOfExcludingThis(aMallocSizeOf);
|
||||||
n += mResource->SizeOfIncludingThis(aMallocSizeOf);
|
n += mResource->SizeOfIncludingThis(aMallocSizeOf);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
CallStack mFirstSeen; // first site from which the resource appeared
|
CallStack mFirstSeen; // first site from which the resource appeared
|
||||||
HashEntryArray mOrderedLT; // this <_o Other
|
HashEntryArray mOrderedLT; // this <_o Other
|
||||||
|
HashEntryArray mExternalRefs; // hash entries that reference this
|
||||||
const T* mResource;
|
const T* mResource;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -286,12 +289,28 @@ public:
|
|||||||
mOrdering.Put(aResource, new OrderingEntry(aResource));
|
mOrdering.Put(aResource, new OrderingEntry(aResource));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nb: implementing a Remove() method makes the detector "more
|
void Remove(T* aResource)
|
||||||
// unsound." By removing a resource from the orderings, deadlocks
|
{
|
||||||
// may be missed that would otherwise have been found. However,
|
PRAutoLock _(mLock);
|
||||||
// removing resources possibly reduces the # of false positives,
|
|
||||||
// and additionally saves space. So it's a trade off; we have
|
OrderingEntry* entry = mOrdering.Get(aResource);
|
||||||
// chosen to err on the side of caution and not implement Remove().
|
|
||||||
|
// Iterate the external refs and remove the entry from them.
|
||||||
|
HashEntryArray& refs = entry->mExternalRefs;
|
||||||
|
for (index_type i = 0; i < refs.Length(); i++) {
|
||||||
|
refs[i]->mOrderedLT.RemoveElementSorted(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate orders and remove this entry from their refs.
|
||||||
|
HashEntryArray& orders = entry->mOrderedLT;
|
||||||
|
for (index_type i = 0; i < orders.Length(); i++) {
|
||||||
|
orders[i]->mExternalRefs.RemoveElementSorted(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now the entry can be safely removed.
|
||||||
|
mOrdering.Remove(aResource);
|
||||||
|
delete aResource;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CheckAcquisition This method is called after acquiring |aLast|,
|
* CheckAcquisition This method is called after acquiring |aLast|,
|
||||||
@@ -372,6 +391,7 @@ public:
|
|||||||
// poset. this is fine, but we now need to add this
|
// poset. this is fine, but we now need to add this
|
||||||
// ordering constraint.
|
// ordering constraint.
|
||||||
current->mOrderedLT.InsertElementSorted(proposed);
|
current->mOrderedLT.InsertElementSorted(proposed);
|
||||||
|
proposed->mExternalRefs.InsertElementSorted(current);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user