Closed Bug 866681 Opened 12 years ago Closed 10 years ago

Make ContentUnbinder use DeferredFinalize

Categories

(Core :: DOM: Core & HTML, defect, P3)

defect

Tracking

()

RESOLVED FIXED
mozilla41
Tracking Status
firefox41 --- fixed

People

(Reporter: mccr8, Assigned: mccr8)

References

Details

Attachments

(2 files, 6 obsolete files)

Some classes, like DOM trees and nsCSSStyleSheetInner, can take a long time to destroy. Each class like this could just implement its own lazy content blaster, but there is some overlap in how high level scheduling gets implemented, and we don't really want every instance of this firing off its own random runnables, causing extra jankiness while the CC and other of these delayed destroyers are running. Instead, we can define a DelayedDestroyer class with two methods: DestroySome(uint32_t aSliceBudget); DestroyAll(); Classes would register a DelayedDestroyer with the CC, which would keep a list of them, and start processing them in its work slices, once unrooting was complete. Classes like the Lazy Content Blaster that want to put a lot of stuff into each destroyer could maintain a weak pointer to their most recent destroyer (cleared in the destructor). One question would be how to schedule work when destroyers are registered while the CC isn't running.
Priority: -- → P3
This is only useful once unlinking is incremental.
Depends on: 926533
No longer depends on: IncrementalCC
The lazy rule destroyer looks to be useful even without incremental unlinking. IncrementalFinalizeRunnable is a similar existing class, as is ContentUnbinder. I'm not sure if we have any others. They should all at least share the same implementation, even if they can't share the exact same instance (for instance, IFR may want to key off the start and end of the GC, rather than CC).
No longer depends on: 926533
I think the right thing to do here is to make IncrementalFinalizeRunnable the one true way to do incremental destruction of stuff. I have a patch in progress to make ContentUnbinder use it.
Part of this will involve things like flushing the DeferredFinalize stuff at the start of a CC.
Assignee: nobody → continuation
Component: XPCOM → DOM
Summary: Add general deferred destroyer mechanism to the cycle collector → Make ContentUnbinder use DeferredFinalize
Whiteboard: [Snappy]
Depends on: 1113300
try run: https://treeherder.mozilla.org/ui/#/jobs?repo=try&revision=cd1f9777841e I'll attach the real meat of things for review once the SegmentedVector API stuff is reviewed.
Attachment #8540735 - Flags: review?(bugs)
Comment on attachment 8540735 [details] [diff] [review] part 1 - Delete trailing whitespace from FragmentOrElement. Well, I want to think a little more about my whole approach here, so I'll just cancel the review for now.
Attachment #8540735 - Flags: review?(bugs)
Here's a new version of this that does not use a segmented vector. I did some local testing with techcrunch page close, and it didn't have more than about 150 items in the array, so maybe segmentation isn't needed?
Depends on: 1155303
Attachment #8538691 - Attachment is obsolete: true
Attachment #8540735 - Attachment is obsolete: true
Attachment #8592363 - Attachment is obsolete: true
This also makes DeferredFinalize be synchronously finished off at the start of a CC, and started up at the end of the CC.
I'm hitting some weird reentrance assertion in the GC: https://treeherder.mozilla.org/#/jobs?repo=try&revision=e3135008e064 I could reproduce locally by closing the browser with a page open.
Comment on attachment 8593633 [details] [diff] [review] part 1 - Remove trailing whitespace from FragmentOrElement. This landed separately.
Attachment #8593633 - Attachment is obsolete: true
try run: https://treeherder.mozilla.org/#/jobs?repo=try&revision=235585197a3b dt1 is failed 100% of the time on this push, but it is almost permafail on inbound, so I choose to believe it is not my fault.
We need to know this so we can decide at the end of the CC if we should dispatch deferred things immediately, or let them run incrementally.
Attachment #8604808 - Flags: review?(bugs)
This patch makes ContentUnbinder use the standard DeferredFinalize mechanism. The actual content things are stored in a segmented vector. This does slightly change the behavior of the content unbinder. We no longer clear it in xpcom-shutdown, or in cycle-collector-begin. Instead, we will only clear it at the end of GC, which is where it is cleared right now. I tried to preserve that behavior, but it was causing some weird reentrance assertion inside the GC that I couldn't figure out. I think it should be okay because we GC so much. At the end of a CC we start up incremental deferred finalize destruction, incrementally if all slices of the CC were incremental, or synchronously otherwise, so that at shutdown and for forced CCs we destroy things immediately. This part unfortunately requires making the FinalizeDeferredThings stuff public. Alternatively, that could be moved inside EndCycleCollectionCallback if you think that is better, though that requires a little more code shuffling.
Attachment #8593634 - Attachment is obsolete: true
Attachment #8593635 - Attachment is obsolete: true
Attachment #8604813 - Flags: review?(bugs)
Attachment #8604808 - Flags: review?(bugs) → review+
Oh, another minor change is that the content unbinder starts at the end of the CC rather than during unlinking.
Comment on attachment 8604813 [details] [diff] [review] part 2 - Make ContentUnbinder use DeferredFinalize. >+ static bool >+ DeferredFinalize(uint32_t aSlice, void* aData) Could you rename aSlice to aSliceBudget or some such >+ if (contentArray->Length() == 0) { >+ delete contentArray; Urm. Somewhat ugly to see manual delete, but I guess we have no other options here.
Attachment #8604813 - Flags: review?(bugs) → review+
Depends on: 1165469
This was mostly backed out in bug 1177627 (but not entirely which is why I'm not reopening...).
Component: DOM → DOM: Core & HTML
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: