thakis pointed me at this ASAN failure on unit tests, that was blamed on my CL: https://build.chromium.org/p/chromium.memory/builders/Mac%20ASan%2064%20Tests%20%281%29/builds/12543/steps/webkit_unit_tests%20on%20Mac-10.9/logs/All_ParameterizedVisualViewportTest.ScrollIntoViewFractionalOffset_1
The underlying problem here is a dangling-pointer issue in Oilpan, as follows:
The objects at play here are:
PaintLayer (non-GC)
PaintLayerScrollableArea (GC)
ScrollAnimatorMac (GC)
BlinkScrollbarPainterControllerDelegate (Obj-C)
PaintLayer is owned by the LayoutView.
PaintLayer has Member<PaintLayerScrollableArea>, and PaintLayerScrollableArea has a PaintLayer& back.
PaintLayerScrollableArea owns ScrollAnimatorMac, which in turn owns BlinkScrollbarPainterControllerDelegate.
AppKit holds a raw pointer to BlinkScrollbarPainterControllerDelegate (unset when ScrollAnimatorMac is destroyed),
When we navigate, LayoutView::willBeDestroyed is called, which destroys the PaintLayer. However, it does not destroy the PaintLayerScrollableArea (since the heap hasn't been collected yet). Thus the rest of the objects remain alive.
Then at some point, AppKit calls back by sending |-scrollerImpPair:updateScrollerStyleForNewRecommendedScrollerStyle:| to the delegate, and we make a series of calls walking back toward PaintLayer. Unfortunately, the PaintLayer& held by PaintLayerScrollableArea is dangling, leading to the ASAN failure (and possibly worse behaviour in non-sanitizer builds).
I'd appreciate advice from Oilpan people about how to handle this. PaintLayerScrollableArea could hold a weak pointer and be able to handle its layer pointer being null, but that seems like quite a large change. Or perhaps PaintLayer should call a dispose method on PaintLayerScrollableArea that causes it to put the ScrollAnimator in a "waiting to be collected" state (also seems non-trivial).
Comment 1 by sigbjo...@opera.com
, Mar 1 2016