Bug 1141089 - Add more asserts for DisplayItemData, trying to catch whether we're accessing deleted instances. r=roc

This commit is contained in:
Markus Stange 2015-04-21 14:13:54 -04:00
parent 448a562cc5
commit c14d806798

View File

@ -49,6 +49,8 @@ namespace mozilla {
class PaintedDisplayItemLayerUserData;
static nsTHashtable<nsPtrHashKey<FrameLayerBuilder::DisplayItemData>>* sAliveDisplayItemDatas;
FrameLayerBuilder::DisplayItemData::DisplayItemData(LayerManagerData* aParent, uint32_t aKey,
Layer* aLayer, nsIFrame* aFrame)
@ -59,10 +61,19 @@ FrameLayerBuilder::DisplayItemData::DisplayItemData(LayerManagerData* aParent, u
, mUsed(true)
, mIsInvalid(false)
{
MOZ_COUNT_CTOR(FrameLayerBuilder::DisplayItemData);
if (!sAliveDisplayItemDatas) {
sAliveDisplayItemDatas = new nsTHashtable<nsPtrHashKey<FrameLayerBuilder::DisplayItemData>>();
}
MOZ_RELEASE_ASSERT(!sAliveDisplayItemDatas->Contains(this));
sAliveDisplayItemDatas->PutEntry(this);
MOZ_RELEASE_ASSERT(mLayer);
if (aFrame) {
AddFrame(aFrame);
}
}
void
@ -164,6 +175,7 @@ FrameLayerBuilder::DisplayItemData::BeginUpdate(Layer* aLayer, LayerState aState
static nsIFrame* sDestroyedFrame = nullptr;
FrameLayerBuilder::DisplayItemData::~DisplayItemData()
{
MOZ_COUNT_DTOR(FrameLayerBuilder::DisplayItemData);
MOZ_RELEASE_ASSERT(mLayer);
for (uint32_t i = 0; i < mFrameList.Length(); i++) {
nsIFrame* frame = mFrameList[i];
@ -174,6 +186,13 @@ FrameLayerBuilder::DisplayItemData::~DisplayItemData()
reinterpret_cast<nsTArray<DisplayItemData*>*>(frame->Properties().Get(LayerManagerDataProperty()));
array->RemoveElement(this);
}
MOZ_RELEASE_ASSERT(sAliveDisplayItemDatas && sAliveDisplayItemDatas->Contains(this));
sAliveDisplayItemDatas->RemoveEntry(this);
if (sAliveDisplayItemDatas->Count() == 0) {
delete sAliveDisplayItemDatas;
sAliveDisplayItemDatas = nullptr;
}
}
const nsTArray<nsIFrame*>&
@ -1397,6 +1416,15 @@ FrameLayerBuilder::FlashPaint(gfxContext *aContext)
aContext->Paint();
}
static FrameLayerBuilder::DisplayItemData*
AssertDisplayItemData(FrameLayerBuilder::DisplayItemData* aData)
{
MOZ_RELEASE_ASSERT(aData);
MOZ_RELEASE_ASSERT(sAliveDisplayItemDatas && sAliveDisplayItemDatas->Contains(aData));
MOZ_RELEASE_ASSERT(aData->mLayer);
return aData;
}
FrameLayerBuilder::DisplayItemData*
FrameLayerBuilder::GetDisplayItemData(nsIFrame* aFrame, uint32_t aKey)
{
@ -1404,9 +1432,7 @@ FrameLayerBuilder::GetDisplayItemData(nsIFrame* aFrame, uint32_t aKey)
static_cast<nsTArray<DisplayItemData*>*>(aFrame->Properties().Get(LayerManagerDataProperty()));
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData* item = array->ElementAt(i);
MOZ_RELEASE_ASSERT(item);
MOZ_RELEASE_ASSERT(item->mLayer);
DisplayItemData* item = AssertDisplayItemData(array->ElementAt(i));
if (item->mDisplayItemKey == aKey &&
item->mLayer->Manager() == mRetainingManager) {
return item;
@ -1701,7 +1727,7 @@ FrameLayerBuilder::GetDisplayItemDataForManager(nsDisplayItem* aItem,
static_cast<nsTArray<DisplayItemData*>*>(aItem->Frame()->Properties().Get(LayerManagerDataProperty()));
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData* item = array->ElementAt(i);
DisplayItemData* item = AssertDisplayItemData(array->ElementAt(i));
if (item->mDisplayItemKey == aItem->GetPerFrameKey() &&
item->mLayer->Manager() == aManager) {
return item;
@ -1718,7 +1744,7 @@ FrameLayerBuilder::HasRetainedDataFor(nsIFrame* aFrame, uint32_t aDisplayItemKey
static_cast<nsTArray<DisplayItemData*>*>(aFrame->Properties().Get(LayerManagerDataProperty()));
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
if (array->ElementAt(i)->mDisplayItemKey == aDisplayItemKey) {
if (AssertDisplayItemData(array->ElementAt(i))->mDisplayItemKey == aDisplayItemKey) {
return true;
}
}
@ -1736,7 +1762,7 @@ FrameLayerBuilder::IterateRetainedDataFor(nsIFrame* aFrame, DisplayItemDataCallb
}
for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData* data = array->ElementAt(i);
DisplayItemData* data = AssertDisplayItemData(array->ElementAt(i));
if (data->mDisplayItemKey != nsDisplayItem::TYPE_ZERO) {
aCallback(aFrame, data);
}
@ -1804,7 +1830,7 @@ FrameLayerBuilder::GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKe
}
for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData *data = array->ElementAt(i);
DisplayItemData *data = AssertDisplayItemData(array->ElementAt(i));
if (data->mDisplayItemKey == aDisplayItemKey) {
return data->mLayer;
@ -1825,6 +1851,7 @@ FrameLayerBuilder::GetDebugSingleOldLayerForFrame(nsIFrame* aFrame)
Layer* layer = nullptr;
for (DisplayItemData* data : *array) {
AssertDisplayItemData(data);
if (layer && layer != data->mLayer) {
// More than one layer assigned, bail.
return nullptr;
@ -4874,7 +4901,7 @@ FrameLayerBuilder::InvalidateAllLayersForFrame(nsIFrame *aFrame)
static_cast<nsTArray<DisplayItemData*>*>(aFrame->Properties().Get(LayerManagerDataProperty()));
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
array->ElementAt(i)->mParent->mInvalidateAllLayers = true;
AssertDisplayItemData(array->ElementAt(i))->mParent->mInvalidateAllLayers = true;
}
}
}
@ -4891,7 +4918,7 @@ FrameLayerBuilder::GetDedicatedLayer(nsIFrame* aFrame, uint32_t aDisplayItemKey)
static_cast<nsTArray<DisplayItemData*>*>(aFrame->Properties().Get(LayerManagerDataProperty()));
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData *element = array->ElementAt(i);
DisplayItemData *element = AssertDisplayItemData(array->ElementAt(i));
if (!element->mParent->mLayerManager->IsWidgetLayerManager()) {
continue;
}
@ -4950,7 +4977,7 @@ FrameLayerBuilder::GetPaintedLayerScaleForFrame(nsIFrame* aFrame)
}
for (uint32_t i = 0; i < array->Length(); i++) {
Layer* layer = array->ElementAt(i)->mLayer;
Layer* layer = AssertDisplayItemData(array->ElementAt(i))->mLayer;
ContainerLayer* container = layer->AsContainerLayer();
if (!container ||
!layer->Manager()->IsWidgetLayerManager()) {
@ -5402,7 +5429,7 @@ FrameLayerBuilder::GetMostRecentGeometry(nsDisplayItem* aItem)
// Find our display item data, if it exists, and return its geometry.
uint32_t itemPerFrameKey = aItem->GetPerFrameKey();
for (uint32_t i = 0; i < dataArray->Length(); i++) {
DisplayItemData* data = dataArray->ElementAt(i);
DisplayItemData* data = AssertDisplayItemData(dataArray->ElementAt(i));
if (data->GetDisplayItemKey() == itemPerFrameKey) {
return data->GetGeometry();
}