Closed
Bug 937766
Opened 11 years ago
Closed 11 years ago
ICC: Safely allow objects to die in between ICC slices
Categories
(Core :: XPCOM, defect)
Core
XPCOM
Tracking
()
RESOLVED
FIXED
mozilla28
Tracking | Status | |
---|---|---|
firefox28 | --- | fixed |
People
(Reporter: mccr8, Assigned: mccr8)
References
Details
(Whiteboard: [qa-])
Attachments
(5 files)
6.72 KB,
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
9.78 KB,
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
4.82 KB,
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
2.42 KB,
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
4.76 KB,
patch
|
smaug
:
review+
|
Details | Diff | Splinter Review |
To safely run incremental cycle collection, the CC must be able to deal with objects dying while the CC is running, because the rest of the browser is allowed to do whatever it wants, and the CC graph holds pointers to these objects.
There are three categories of objects, which must all must be removed from the graph if they die during a CC: snow-white-able objects, JS objects, and XPCWN/XPCWJS (these are C++, but do not support snow-white.
For snow-whitable objects (the normal case for C++ objects), this is just a matter of removing dying objects from the graph in SnowWhiteKiller. (Pre snow white, handling this was pretty gross.)
For JS objects, the CC has no way to see when an individual JS object dies, but they can only die during a garbage collection. Therefore, if when a GC starts there is an ICC in progress, the CC finishes itself synchronously. This is potentially pretty janky, but hopefully it won't happen much.
For XPCWN and XPCWJ, I add a new callback nsCycleCollector_objectDying() that simply removes the object in question from the graph, and call it from the destructor of those classes.
When an object is removed is removed from the graph, the mPointer and mPaticipant fields of its PtrInfo are nulled out. This requires adding a bunch of null checks to the CC to avoid null derefs. Note that because we nulled them out, we'll just get a safe null deref if we forget a check.
A final bit of oddness that we must deal with is that the traversal of nodes caches information in an array gCCBlackMarkedNodes, which weakly holds pointers to nodes that can die. This data structure must be modified a bit to allow dying objects to be removed.
Assignee | ||
Comment 1•11 years ago
|
||
Rather than hacking up weird infrastructure for dealing with XPCWN and XPCWJ, as described in comment 0, I am planning on turning them into regular purple buffered classes (bug 944492 and bug 942528).
Assignee | ||
Comment 2•11 years ago
|
||
Assignee | ||
Comment 3•11 years ago
|
||
Huh, I have no idea why that didn't build. It builds locally for me. Maybe it will work if I push again...
https://tbpl.mozilla.org/?tree=Try&rev=490cf835e66f
Assignee | ||
Comment 4•11 years ago
|
||
I'm just bad at pushing chained git repos...
https://tbpl.mozilla.org/?tree=Try&rev=3072def4e830
Assignee | ||
Comment 5•11 years ago
|
||
With ICC, arbitrary other activity can happen while nodes are in gCCBlackMarkedNodes,
so the nodes can die, because gCCBlackMarkedNodes only holds a weak reference.
To avoid this, remove nodes from gCCBlackMarkedNodes when they are going away.
Attachment #8342406 -
Flags: review?(bugs)
Assignee | ||
Comment 6•11 years ago
|
||
If we purge snow white objects while ICC is in progress, we need to
make sure to remove anything from the CC graph to avoid dangling pointers.
We don't need to do that after shutdown.
Attachment #8342407 -
Flags: review?(bugs)
Assignee | ||
Comment 7•11 years ago
|
||
When an object dies during an incremental cycle collection, we null out
its mParticipant, so we must add various null checks to avoid crashing
when we reach the CC graph representation of an object that has died.
Attachment #8342408 -
Flags: review?(bugs)
Assignee | ||
Comment 8•11 years ago
|
||
Attachment #8342409 -
Flags: review?(bugs)
Assignee | ||
Comment 9•11 years ago
|
||
Running the garbage collector can cause objects in the CC graph to
die, so just finish off an incremental cycle collection when we
start a GC.
Attachment #8342410 -
Flags: review?(bugs)
Comment 10•11 years ago
|
||
Comment on attachment 8342406 [details] [diff] [review]
part 1 - Remove dying nodes from gCCBlackMarkedNodes. r=smaug
>-nsAutoTArray<nsINode*, 1020>* gCCBlackMarkedNodes = nullptr;
>+StaticAutoPtr<nsTHashtable<nsPtrHashKey<nsINode> > > gCCBlackMarkedNodes;
I think you don't need space between > and > these days.
>+static PLDHashOperator
>+VisitBlackMarkedNode(nsPtrHashKey<nsINode>* aEntry, void *)
void*
Attachment #8342406 -
Flags: review?(bugs) → review+
Updated•11 years ago
|
Attachment #8342407 -
Flags: review?(bugs) → review+
Updated•11 years ago
|
Attachment #8342408 -
Flags: review?(bugs) → review+
Updated•11 years ago
|
Attachment #8342409 -
Flags: review?(bugs) → review+
Updated•11 years ago
|
Attachment #8342410 -
Flags: review?(bugs) → review+
Assignee | ||
Comment 11•11 years ago
|
||
Thanks for the reviews! I fixed the two things you pointed out for patch 1.
remote: https://hg.mozilla.org/integration/mozilla-inbound/rev/4dcb040e3c84
remote: https://hg.mozilla.org/integration/mozilla-inbound/rev/b015eac4566f
remote: https://hg.mozilla.org/integration/mozilla-inbound/rev/9a4f57330003
remote: https://hg.mozilla.org/integration/mozilla-inbound/rev/abc785d60d75
remote: https://hg.mozilla.org/integration/mozilla-inbound/rev/edb01fe9d000
https://hg.mozilla.org/mozilla-central/rev/4dcb040e3c84
https://hg.mozilla.org/mozilla-central/rev/b015eac4566f
https://hg.mozilla.org/mozilla-central/rev/9a4f57330003
https://hg.mozilla.org/mozilla-central/rev/abc785d60d75
https://hg.mozilla.org/mozilla-central/rev/edb01fe9d000
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla28
status-firefox28:
--- → fixed
Whiteboard: [qa-]
You need to log in
before you can comment on or make changes to this bug.
Description
•