Closed
Bug 1288817
Opened 8 years ago
Closed 8 years ago
Refcount XPCNativeScriptableShared
Categories
(Core :: XPConnect, defect)
Core
XPConnect
Tracking
()
RESOLVED
FIXED
mozilla51
People
(Reporter: mccr8, Assigned: mccr8)
References
Details
Attachments
(4 files, 4 obsolete files)
XPCNativeScriptableShared is held alive via various XPCWrappedNative things, and its lifetime is currently managed by the GC, through an odd Mark() system. Besides the complexity of this system, it is bad because we only free these objects in full GCs, which we'd like to reduce or eliminate. It seems like we maybe mark all XPCWNs and protos in all GCs, but I think it would be better to just work on eliminating this bizarre setup. The only fields of XPCNativeScriptableShared are a js::Class and a XPCNativeScriptableFlags (which is just an integer), so I don't think they can point to any JS GC things. Therefore, I think we can just refcount these objects.
Assignee | ||
Comment 1•8 years ago
|
||
I still need to clean up my patches some more, but I have something that seems to work. try run: https://treeherder.mozilla.org/#/jobs?repo=try&revision=6fdb87155d07
Assignee | ||
Comment 2•8 years ago
|
||
ASan try run: https://treeherder.mozilla.org/#/jobs?repo=try&revision=9008017e28f2
Assignee | ||
Comment 3•8 years ago
|
||
Bobby, is it okay if billm reviews this and the other bugs (bug 1288870, bug 1288909) to use refcounting instead of the weird Mark() GC stuff? These patches should only affect the lifetime management of the classes, not anything about what they do, and Bill understands that as well as anybody (or did at some point). Also, do you think XPCNativeScriptableSharedMap::GetNewOrUsed() is performance critical still? My patches here will add a heap allocation on the fast path, which hopefully won't matter, but I haven't measured anything. Thanks.
Flags: needinfo?(bobbyholley)
Assignee | ||
Comment 4•8 years ago
|
||
This adds a heap allocation in XPCNativeScriptableSharedMap::GetNewOrUsed() on the fast path. Hopefully that code is not hot enough for it to matter. I could work around this if needed, but it would be ugly. mNativeScriptableSharedMap has a weak pointer to XPCNativeScriptableShared. I moved this removal from XPCJSRuntime::FinalizeCallback() to the dtor. There are two types of scriptable: one is a dummy one created in GetNewOrUsed() to do a lookup, and the other is a fully filled out one. The dummy one is not added to the hashtable, and may have had its name stolen if we created a new scriptable. The latter makes it so that you crash if you try to look it up in the hashtable anyways, so this patch only looks up fully filled out scriptables. This patch also removes MOZ_COUNT_CTOR/DTOR because they are not needed for refcounted classes.
Assignee | ||
Comment 5•8 years ago
|
||
Nothing depends on the value of the mark bit now.
Assignee | ||
Comment 6•8 years ago
|
||
Comment 7•8 years ago
|
||
(In reply to Andrew McCreight [:mccr8] from comment #3) > Bobby, is it okay if billm reviews this and the other bugs (bug 1288870, bug > 1288909) to use refcounting instead of the weird Mark() GC stuff? These > patches should only affect the lifetime management of the classes, not > anything about what they do, and Bill understands that as well as anybody > (or did at some point). Yep, you and Bill understand the XPConnect lifetime management as well as I do, probably more. Excited to hear it's going to get simpler! :-)
Flags: needinfo?(bobbyholley)
Assignee | ||
Updated•8 years ago
|
Attachment #8774396 -
Flags: review?(wmccloskey)
Assignee | ||
Updated•8 years ago
|
Attachment #8774397 -
Flags: review?(wmccloskey)
Assignee | ||
Updated•8 years ago
|
Attachment #8774398 -
Flags: review?(wmccloskey)
Assignee | ||
Comment 8•8 years ago
|
||
This adds a heap allocation in XPCNativeScriptableSharedMap::GetNewOrUsed() on the fast path. Hopefully that code is not hot enough for it to matter. I could work around this if needed, but it would be ugly. mNativeScriptableSharedMap has a weak pointer to XPCNativeScriptableShared. I moved this removal from XPCJSRuntime::FinalizeCallback() to the dtor. There are two types of scriptable: one is a dummy one created in GetNewOrUsed() to do a lookup, and the other is a fully filled out one. The dummy one is not added to the hashtable, and may have had its name stolen if we created a new scriptable. The latter makes it so that you crash if you try to look it up in the hashtable anyways, so this patch only looks up fully filled out scriptables. This patch also removes MOZ_COUNT_CTOR/DTOR because they are not needed for refcounted classes. Review commit: https://reviewboard.mozilla.org/r/68420/diff/#index_header See other reviews: https://reviewboard.mozilla.org/r/68420/
Attachment #8776718 -
Flags: review?(wmccloskey)
Attachment #8776719 -
Flags: review?(wmccloskey)
Attachment #8776720 -
Flags: review?(wmccloskey)
Assignee | ||
Comment 9•8 years ago
|
||
Nothing depends on the value of the mark bit now. Review commit: https://reviewboard.mozilla.org/r/68422/diff/#index_header See other reviews: https://reviewboard.mozilla.org/r/68422/
Assignee | ||
Comment 10•8 years ago
|
||
Review commit: https://reviewboard.mozilla.org/r/68424/diff/#index_header See other reviews: https://reviewboard.mozilla.org/r/68424/
Assignee | ||
Updated•8 years ago
|
Attachment #8774396 -
Attachment is obsolete: true
Attachment #8774396 -
Flags: review?(wmccloskey)
Assignee | ||
Updated•8 years ago
|
Attachment #8774397 -
Attachment is obsolete: true
Attachment #8774397 -
Flags: review?(wmccloskey)
Assignee | ||
Updated•8 years ago
|
Attachment #8774398 -
Attachment is obsolete: true
Attachment #8774398 -
Flags: review?(wmccloskey)
Comment 11•8 years ago
|
||
mozreview-review |
Comment on attachment 8776718 [details] Bug 1288817, part 1 - Make XPCNativeScriptableShared refcounted. https://reviewboard.mozilla.org/r/68420/#review68558 ::: js/xpconnect/src/XPCMaps.h:500 (Diff revision 1) > class XPCNativeScriptableSharedMap > { > public: > struct Entry : public PLDHashEntryHdr > { > XPCNativeScriptableShared* key; Please comment that this is a weak reference. The hash table entry gets cleared in the XPCNSS destructor. ::: js/xpconnect/src/XPCWrappedNativeJSOps.cpp:1062 (Diff revision 1) > mJSClass.oOps = &XPC_WN_ObjectOpsWithEnumerate; > } > > +XPCNativeScriptableShared::~XPCNativeScriptableShared() > +{ > + if (mJSClass.cOps) { Please comment that this can be null for an XPCNSS that was created with populate=false. ::: js/xpconnect/src/xpcprivate.h:1552 (Diff revision 1) > > const JSClass* > GetJSClass() {return mShared->GetJSClass();} > > void > - SetScriptableShared(XPCNativeScriptableShared* shared) {mShared = shared;} > + SetScriptableShared(already_AddRefed<XPCNativeScriptableShared>&& shared) {mShared = shared;} Can you fix the horrible formatting here? ::: js/xpconnect/src/xpcprivate.h:1565 (Diff revision 1) > void AutoTrace(JSTracer* trc) {} > > protected: > explicit XPCNativeScriptableInfo(nsIXPCScriptable* scriptable) > - : mCallback(scriptable), mShared(nullptr) > + : mCallback(scriptable) > {MOZ_COUNT_CTOR(XPCNativeScriptableInfo);} And especially here. My god.
Attachment #8776718 -
Flags: review?(wmccloskey) → review+
Comment 12•8 years ago
|
||
mozreview-review |
Comment on attachment 8776719 [details] Bug 1288817, part 2 - Remove marking methods from XPCNativeScriptableShared and XPCNativeScriptableFlags. https://reviewboard.mozilla.org/r/68422/#review68564 ::: js/xpconnect/src/xpcprivate.h:1441 (Diff revision 1) > - uint32_t GetFlags() const {return mFlags & ~XPC_WN_SJSFLAGS_MARK_FLAG;} > + uint32_t GetFlags() const {return mFlags;} > void SetFlags(uint32_t flags) {mFlags = flags;} Same with this formatting. Go nuts here if you want.
Attachment #8776719 -
Flags: review?(wmccloskey) → review+
Comment 13•8 years ago
|
||
mozreview-review |
Comment on attachment 8776720 [details] Bug 1288817, part 3 - Stop calling XPCNativeScriptableInfo::Mark() from various places because it doesn't do anything. https://reviewboard.mozilla.org/r/68424/#review68566
Attachment #8776720 -
Flags: review?(wmccloskey) → review+
Assignee | ||
Comment 14•8 years ago
|
||
I'll add comments in both places, that's a good point. I'll fix the formatting, too, in those places you pointed out. Generally, I was trying to not fix formatting on lines I didn't actually touch, as I was worried I'd just end up getting sucked into spending a bunch of time on fixing formatting.
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment 18•8 years ago
|
||
Pushed by amccreight@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/824dd062b8e3 part 1 - Make XPCNativeScriptableShared refcounted. r=billm https://hg.mozilla.org/integration/autoland/rev/79df306f1d11 part 2 - Remove marking methods from XPCNativeScriptableShared and XPCNativeScriptableFlags. r=billm https://hg.mozilla.org/integration/autoland/rev/1bc60cfdc088 part 3 - Stop calling XPCNativeScriptableInfo::Mark() from various places because it doesn't do anything. r=billm
Comment 19•8 years ago
|
||
Backed out for startup precompilation bustage. https://hg.mozilla.org/integration/autoland/rev/58f7284ec7fe447807ee7a0d34b21dd154a9321c https://hg.mozilla.org/integration/autoland/rev/f710f7b260052f0dfc570b1f42f89cf17d891142 https://hg.mozilla.org/integration/autoland/rev/48873ebb15604bc0f5051d5d1938b7a27d6e8caf Push with failures: https://treeherder.mozilla.org/#/jobs?repo=autoland&revision=1bc60cfdc08876fdb74e5d607418055c1f120ddf
Flags: needinfo?(continuation)
Assignee | ||
Comment 20•8 years ago
|
||
The breakage was in opt builds not debug builds. Very odd. I'll have to try to reproduce locally, as there's no obvious difference in the code in opt builds.
Flags: needinfo?(continuation)
Assignee | ||
Comment 21•8 years ago
|
||
Philor pointed out that opt Android XPCShell is also very orange. It looks like there are a bunch of UAF crashes inside markGrayReferences: https://treeherder.mozilla.org/logviewer.html#?job_id=1830794&repo=autoland
Assignee | ||
Comment 22•8 years ago
|
||
I can reproduce this locally with ./mach xpcshell-test devtools/client/webconsole/new-console-output/test/store/ The stack basically looks the same as Android. I'll need to use an ASan build to figure out what is going on.
Assignee | ||
Comment 23•8 years ago
|
||
The problem is that XPCWrappedNative::SystemIsBeingShutDown() just unconditionally destroys the mScriptableInfo, which can the last release of XPCNativeScriptableShared, which in turn causes a js::ClassOps that is still being used by a JS object to be destroyed. To fix this, I match the existing behavior and simply leak all XPCNativeScriptableShared that are alive once nsXPConnect::mShuttingDown is set to true. Some of my other refcounting patches will need a similar treatment. I'm doing a full try run, but this fixes the issue for me locally: https://treeherder.mozilla.org/#/jobs?repo=try&revision=199c6724c74f (I reproduced in an ASan build by removing the #define for NS_FREE_PERMANENT_DATA from nscore.h.)
Assignee | ||
Comment 24•8 years ago
|
||
I can't submit an updated patch using MozReview for some reason, so here are my changes. (I added some minor cleanups, too.) I'll land this folded into part 1. Intentionally leak any XPCNativeScriptableShared that are alive late in shutdown to avoid use-after-frees from JS objects that are still using those js::ClassOps. This matches the existing behavior, which does not sweep these ScriptableShared during shutdown. (This came up in opt xpcshell tests.) MozReview-Commit-ID: I3m2BtlZc3b
Attachment #8781225 -
Flags: review?(wmccloskey)
Assignee | ||
Comment 25•8 years ago
|
||
> Some of my other refcounting patches will need a similar treatment.
The other two classes I converted to refcounting aren't like this, it turns out.
Assignee | ||
Comment 26•8 years ago
|
||
Bill pointed out that we could just skip deleting mScriptableInfo. This is the only place on the heap that holds a strong reference to these shared objects, so I think it will end up having the same effect as my other patch. I was just being overly paranoid about other places possibly dropping their references. It fixed the problem for me locally, and I'll try a Linux debug+opt try run to make sure before landing. https://treeherder.mozilla.org/#/jobs?repo=try&revision=2f1c51db8a55 Stop destroying mScriptableInfo in XPCWrappedNative's SystemIsBeingShutDown(), because that will end up destroying XPCNativeScriptableShared, while their js::ClassOps are still in use by JS objects. This matches the existing behavior, which does not sweep these ScriptableShared during shutdown. (This came up in opt xpcshell tests.) MozReview-Commit-ID: 3kwMr8xt9RA
Attachment #8781274 -
Flags: review?(wmccloskey)
Assignee | ||
Updated•8 years ago
|
Attachment #8781225 -
Attachment is obsolete: true
Attachment #8781225 -
Flags: review?(wmccloskey)
Attachment #8781274 -
Flags: review?(wmccloskey) → review+
Comment 27•8 years ago
|
||
Pushed by amccreight@mozilla.com: https://hg.mozilla.org/integration/mozilla-inbound/rev/c5be273c8372 part 1 - Make XPCNativeScriptableShared refcounted. r=billm https://hg.mozilla.org/integration/mozilla-inbound/rev/6bb9524f0036 part 2 - Remove marking methods from XPCNativeScriptableShared and XPCNativeScriptableFlags. r=billm https://hg.mozilla.org/integration/mozilla-inbound/rev/6b3f96dbbf28 part 3 - Stop calling XPCNativeScriptableInfo::Mark() from various places because it doesn't do anything. r=billm
Comment 28•8 years ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/c5be273c8372 https://hg.mozilla.org/mozilla-central/rev/6bb9524f0036 https://hg.mozilla.org/mozilla-central/rev/6b3f96dbbf28
Status: NEW → RESOLVED
Closed: 8 years ago
status-firefox51:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla51
You need to log in
before you can comment on or make changes to this bug.
Description
•