author | Gabor Krizsanits <gkrizsanits@mozilla.com> |
Thu, 04 Apr 2013 11:27:43 +0200 | |
changeset 127635 | 36fcd3edc6b832c818bbf8e504b4c02ecb0266ca |
parent 127634 | 788e34b8872e21e19909570dfceeeda37bab9445 |
child 127636 | 372ae5eae8b9041cf58783980ac91ad6fdbdbb91 |
push id | 24509 |
push user | ryanvm@gmail.com |
push date | Fri, 05 Apr 2013 00:57:47 +0000 |
treeherder | mozilla-central@55f9e3e3dae7 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bholley |
bugs | 820170 |
milestone | 23.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -291,16 +291,24 @@ EnableUniversalXPConnect(JSContext *cx) // tests. XPCWrappedNativeScope *scope = priv->scope; if (!scope) return true; XPCCallContext ccx(NATIVE_CALLER, cx); return nsXPCComponents::AttachComponentsObject(ccx, scope); } +JSObject * +GetJunkScope() +{ + XPCJSRuntime *self = nsXPConnect::GetRuntimeInstance(); + NS_ENSURE_TRUE(self, nullptr); + return self->GetJunkScope(); +} + } static void CompartmentDestroyedCallback(JSFreeOp *fop, JSCompartment *compartment) { XPCJSRuntime* self = nsXPConnect::GetRuntimeInstance(); if (!self) return; @@ -2646,17 +2654,18 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* mVariantRoots(nullptr), mWrappedJSRoots(nullptr), mObjectHolderRoots(nullptr), mWatchdogLock(nullptr), mWatchdogWakeup(nullptr), mWatchdogThread(nullptr), mWatchdogHibernating(false), mLastActiveTime(-1), - mExceptionManagerNotAvailable(false) + mExceptionManagerNotAvailable(false), + mJunkScope(nullptr) #ifdef DEBUG , mObjectToUnlink(nullptr) #endif { #ifdef XPC_CHECK_WRAPPERS_AT_SHUTDOWN DEBUG_WrappedNativeHashtable = JS_NewDHashTable(JS_DHashGetStubOps(), nullptr, sizeof(JSDHashEntryStub), 128); @@ -2995,8 +3004,41 @@ void XPCJSRuntime::RemoveGCCallback(JSGCCallback cb) { NS_ASSERTION(cb, "null callback"); bool found = extraGCCallbacks.RemoveElement(cb); if (!found) { NS_ERROR("Removing a callback which was never added."); } } + +JSObject * +XPCJSRuntime::GetJunkScope() +{ + if (!mJunkScope) { + JS::Value v; + SafeAutoJSContext cx; + SandboxOptions options; + options.sandboxName.AssignASCII("XPConnect Junk Compartment"); + JSAutoRequest ac(cx); + nsresult rv = xpc_CreateSandboxObject(cx, &v, + nsContentUtils::GetSystemPrincipal(), + options); + + NS_ENSURE_SUCCESS(rv, nullptr); + + mJunkScope = js::UnwrapObject(&v.toObject()); + JS_AddNamedObjectRoot(cx, &mJunkScope, "XPConnect Junk Compartment"); + } + return mJunkScope; +} + +void +XPCJSRuntime::DeleteJunkScope() +{ + if(!mJunkScope) + return; + + JSContext *cx = mJSContextStack->GetSafeJSContext(); + JSAutoRequest ac(cx); + JS_RemoveObjectRoot(cx, &mJunkScope); + mJunkScope = nullptr; +}
--- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -87,16 +87,17 @@ nsXPConnect::nsXPConnect() char* reportableEnv = PR_GetEnv("MOZ_REPORT_ALL_JS_EXCEPTIONS"); if (reportableEnv && *reportableEnv) gReportAllJSExceptions = 1; } nsXPConnect::~nsXPConnect() { + mRuntime->DeleteJunkScope(); nsCycleCollector_forgetJSRuntime(); JSContext *cx = nullptr; if (mRuntime) { // Create our own JSContext rather than an XPCCallContext, since // otherwise we will create a new safe JS context and attach a // components object that won't get GCed. cx = JS_NewContext(mRuntime->GetJSRuntime(), 8192);
--- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -904,16 +904,18 @@ public: bool XBLScopesEnabled() { return gXBLScopesEnabled; } size_t SizeOfIncludingThis(nsMallocSizeOfFun mallocSizeOf); AutoMarkingPtr** GetAutoRootsAdr() {return &mAutoRoots;} + JSObject* GetJunkScope(); + void DeleteJunkScope(); private: XPCJSRuntime(); // no implementation XPCJSRuntime(nsXPConnect* aXPConnect); // The caller must be holding the GC lock void RescheduleWatchdog(XPCContext* ccx); static void WatchdogMain(void *arg); @@ -954,16 +956,17 @@ private: PRLock *mWatchdogLock; PRCondVar *mWatchdogWakeup; PRThread *mWatchdogThread; nsTArray<JSGCCallback> extraGCCallbacks; bool mWatchdogHibernating; PRTime mLastActiveTime; // -1 if active NOW nsRefPtr<XPCIncrementalReleaseRunnable> mReleaseRunnable; JS::GCSliceCallback mPrevGCSliceCallback; + JSObject* mJunkScope; nsCOMPtr<nsIException> mPendingException; nsCOMPtr<nsIExceptionManager> mExceptionManager; bool mExceptionManagerNotAvailable; #define XPCCCX_STRING_CACHE_SIZE 2 // String wrapper entry, holds a string, and a boolean that tells
--- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -402,16 +402,30 @@ ReportJSRuntimeExplicitTreeStats(const J bool Throw(JSContext *cx, nsresult rv); /** * Every global should hold a native that implements the nsIGlobalObject interface. */ nsIGlobalObject * GetNativeForGlobal(JSObject *global); + +/** + * In some cases a native object does not really belong to any compartment (XBL, + * document created from by XHR of a worker, etc.). But when for some reason we + * have to wrap these natives (because of an event for example) instead of just + * wrapping them into some random compartment we find on the context stack (like + * we did previously) a default compartment is used. This function returns that + * compartment's global. It is a singleton on the runtime. + * If you find yourself wanting to use this compartment, you're probably doing + * something wrong. Callers MUST consult with the XPConnect module owner before + * using this compartment. If you don't, bholley will hunt you down. + */ +JSObject * +GetJunkScope(); } // namespace xpc nsCycleCollectionParticipant * xpc_JSZoneParticipant(); namespace mozilla { namespace dom {