Bug 1462497 - Part 1: Don't crash if we find an item from the wrong list, and keep looking instead. r=miko, a=RyanVM
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 23 May 2018 10:59:11 +1200
changeset 470920 352f0eb7324c06128a648ad94273ca5cb3a19332
parent 470919 4b2b5c188e2ed608af1cafad23e0bf3cd49b2f62
child 470921 cf8f2940def1269022f5b766f3d19bf2c074a658
push id9267
push userryanvm@gmail.com
push dateFri, 25 May 2018 16:08:23 +0000
treeherdermozilla-beta@bb4d7af3e4ab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmiko, RyanVM
bugs1462497
milestone61.0
Bug 1462497 - Part 1: Don't crash if we find an item from the wrong list, and keep looking instead. r=miko, a=RyanVM We will still crash in Nightly/DevEdition builds (so that we can fix the bug), but we'll just accept the possible duplication of items (and maybe minor rendering issues) for releases. MozReview-Commit-ID: LNzjO8vJjGp
layout/painting/RetainedDisplayListBuilder.cpp
layout/painting/nsDisplayList.h
--- a/layout/painting/RetainedDisplayListBuilder.cpp
+++ b/layout/painting/RetainedDisplayListBuilder.cpp
@@ -330,18 +330,19 @@ public:
 
   bool HasMatchingItemInOldList(nsDisplayItem* aItem, OldListIndex* aOutIndex)
   {
     nsIFrame::DisplayItemArray* items = aItem->Frame()->GetProperty(nsIFrame::DisplayItems());
     // Look for an item that matches aItem's frame and per-frame-key, but isn't the same item.
     for (nsDisplayItem* i : *items) {
       if (i != aItem && i->Frame() == aItem->Frame() &&
           i->GetPerFrameKey() == aItem->GetPerFrameKey()) {
-        *aOutIndex = i->GetOldListIndex(mOldList, mOuterKey);
-        return true;
+        if (i->GetOldListIndex(mOldList, mOuterKey, aOutIndex)) {
+          return true;
+        }
       }
     }
     return false;
   }
 
   bool HasModifiedFrame(nsDisplayItem* aItem) {
     return AnyContentAncestorModified(aItem->FrameForInvalidation());
   }
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -2849,24 +2849,26 @@ public:
   {
 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
     mOldList = reinterpret_cast<uintptr_t>(aList);
     mOldListKey = aListKey;
     mOldNestingDepth = aNestingDepth;
 #endif
     mOldListIndex = aIndex;
   }
-  OldListIndex GetOldListIndex(nsDisplayList* aList, uint32_t aListKey)
-  {
-#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
+  bool GetOldListIndex(nsDisplayList* aList, uint32_t aListKey, OldListIndex* aOutIndex)
+  {
     if (mOldList != reinterpret_cast<uintptr_t>(aList)) {
+#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
       MOZ_CRASH_UNSAFE_PRINTF("Item found was in the wrong list! type %d (outer type was %d at depth %d, now is %d)", GetPerFrameKey(), mOldListKey, mOldNestingDepth, aListKey);
+#endif
+      return false;
     }
-#endif
-    return mOldListIndex;
+    *aOutIndex = mOldListIndex;
+    return true;
   }
 
 protected:
   nsDisplayItem() = delete;
 
   typedef bool (*PrefFunc)(void);
   bool ShouldUseAdvancedLayer(LayerManager* aManager, PrefFunc aFunc) const;
   bool CanUseAdvancedLayer(LayerManager* aManager) const;
@@ -2886,24 +2888,24 @@ protected:
   // nsDisplayList::ComputeVisibility sets this to the visible region
   // of the item by intersecting the current visible region with the bounds
   // of the item. Paint implementations can use this to limit their drawing.
   // Guaranteed to be contained in GetBounds().
   nsRect    mVisibleRect;
 
 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
 public:
-  uintptr_t mOldList = 0;
   uint32_t mOldListKey = 0;
   uint32_t mOldNestingDepth = 0;
   bool mMergedItem = false;
   bool mPreProcessedItem = false;
 protected:
 #endif
   OldListIndex mOldListIndex;
+  uintptr_t mOldList = 0;
 
   bool      mForceNotVisible;
   bool      mDisableSubpixelAA;
   bool      mReusedItem;
   bool      mBackfaceHidden;
 #ifdef MOZ_DUMP_PAINTING
   // True if this frame has been painted.
   bool      mPainted;