зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 12 changesets (bug 899367) for Windows and OSX mochitest failures on a CLOSED TREE.
Backed out changeset 46cf4c3eb447 (bug 899367) Backed out changeset d8a876219fc7 (bug 899367) Backed out changeset d930333f95a7 (bug 899367) Backed out changeset efae8cc0fff8 (bug 899367) Backed out changeset 1dd262d146a6 (bug 899367) Backed out changeset 4c396b8a51d0 (bug 899367) Backed out changeset c8c30176639a (bug 899367) Backed out changeset aaa8fbcf9aaf (bug 899367) Backed out changeset d1a782044a4b (bug 899367) Backed out changeset b2672ab55046 (bug 899367) Backed out changeset fc4deb0b06fa (bug 899367) Backed out changeset b9f1018a609c (bug 899367)
This commit is contained in:
Родитель
6349254839
Коммит
6f0d3838c9
|
@ -66,7 +66,7 @@ NS_IMETHODIMP
|
|||
nsSecurityNameSet::InitializeNameSet(nsIScriptContext* aScriptContext)
|
||||
{
|
||||
AutoJSContext cx;
|
||||
JS::Rooted<JSObject*> global(cx, aScriptContext->GetWindowProxy());
|
||||
JS::Rooted<JSObject*> global(cx, aScriptContext->GetNativeGlobal());
|
||||
JSAutoCompartment ac(cx, global);
|
||||
|
||||
/*
|
||||
|
|
|
@ -908,7 +908,7 @@ nsEventListenerManager::CompileEventHandlerInternal(nsListenerStruct *aListenerS
|
|||
aListenerStruct->mTypeAtom,
|
||||
&argCount, &argNames);
|
||||
|
||||
JSAutoCompartment ac(cx, context->GetWindowProxy());
|
||||
JSAutoCompartment ac(cx, context->GetNativeGlobal());
|
||||
JS::CompileOptions options(cx);
|
||||
options.setFileAndLine(url.get(), lineNo)
|
||||
.setVersion(SCRIPTVERSION_DEFAULT);
|
||||
|
|
|
@ -28,8 +28,6 @@ GetScriptContextFromJSContext(JSContext *cx)
|
|||
return scx;
|
||||
}
|
||||
|
||||
JSObject* GetDefaultScopeFromJSContext(JSContext *cx);
|
||||
|
||||
// A factory function for turning a JS::Value argv into an nsIArray
|
||||
// but also supports an effecient way of extracting the original argv.
|
||||
// Bug 312003 describes why this must be "void *", but argv will be cast to
|
||||
|
|
|
@ -2048,9 +2048,8 @@ nsGlobalWindow::SetOuterObject(JSContext* aCx, JS::Handle<JSObject*> aOuterObjec
|
|||
{
|
||||
JSAutoCompartment ac(aCx, aOuterObject);
|
||||
|
||||
// Inform the nsJSContext, which is the canonical holder of the outer.
|
||||
MOZ_ASSERT(IsOuterWindow());
|
||||
mContext->SetWindowProxy(aOuterObject);
|
||||
// Indicate the default compartment object associated with this cx.
|
||||
js::SetDefaultObjectForContext(aCx, aOuterObject);
|
||||
|
||||
// Set up the prototype for the outer object.
|
||||
JS::Rooted<JSObject*> inner(aCx, JS_GetParent(aOuterObject));
|
||||
|
@ -2362,7 +2361,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
|
|||
CreateOuterObject(newInnerWindow);
|
||||
mContext->DidInitializeContext();
|
||||
|
||||
mJSObject = mContext->GetWindowProxy();
|
||||
mJSObject = mContext->GetNativeGlobal();
|
||||
SetWrapper(mJSObject);
|
||||
} else {
|
||||
JS::Rooted<JSObject*> global(cx,
|
||||
|
@ -2446,7 +2445,11 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
|
|||
newInnerWindow->FastGetGlobalJSObject());
|
||||
#endif
|
||||
|
||||
MOZ_ASSERT(mContext->GetWindowProxy() == mJSObject);
|
||||
// Now that we're connecting the outer global to the inner one,
|
||||
// we must have transplanted it. The JS engine tries to maintain
|
||||
// the global object's compartment as its default compartment,
|
||||
// so update that now since it might have changed.
|
||||
js::SetDefaultObjectForContext(cx, mJSObject);
|
||||
#ifdef DEBUG
|
||||
JS::Rooted<JSObject*> rootedJSObject(cx, mJSObject);
|
||||
JS::Rooted<JSObject*> proto1(cx), proto2(cx);
|
||||
|
|
|
@ -27,8 +27,8 @@ class nsIDOMWindow;
|
|||
class nsIURI;
|
||||
|
||||
#define NS_ISCRIPTCONTEXT_IID \
|
||||
{ 0xf3859ce7, 0x7551, 0x4760, \
|
||||
{ 0x84, 0x29, 0x64, 0x4f, 0x26, 0x1e, 0xdb, 0x91 } }
|
||||
{ 0x1d931a17, 0x453a, 0x47fb, \
|
||||
{ 0x94, 0x66, 0x2d, 0x3e, 0xd1, 0xef, 0x7a, 0xc5 } }
|
||||
|
||||
/* This MUST match JSVERSION_DEFAULT. This version stuff if we don't
|
||||
know what language we have is a little silly... */
|
||||
|
@ -103,6 +103,12 @@ public:
|
|||
**/
|
||||
virtual JSContext* GetNativeContext() = 0;
|
||||
|
||||
/**
|
||||
* Return the native global object for this context.
|
||||
*
|
||||
**/
|
||||
virtual JSObject* GetNativeGlobal() = 0;
|
||||
|
||||
/**
|
||||
* Initialize the context generally. Does not create a global object.
|
||||
**/
|
||||
|
@ -159,12 +165,6 @@ public:
|
|||
* Tell the context we're done reinitializing it.
|
||||
*/
|
||||
virtual void DidInitializeContext() = 0;
|
||||
|
||||
/**
|
||||
* Access the Window Proxy. The setter should only be called by nsGlobalWindow.
|
||||
*/
|
||||
virtual void SetWindowProxy(JS::Handle<JSObject*> aWindowProxy) = 0;
|
||||
virtual JSObject* GetWindowProxy() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContext, NS_ISCRIPTCONTEXT_IID)
|
||||
|
|
|
@ -80,9 +80,7 @@
|
|||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/CanvasRenderingContext2DBinding.h"
|
||||
#include "mozilla/CycleCollectedJSRuntime.h"
|
||||
|
||||
#include "nsCycleCollectionNoteRootCallback.h"
|
||||
#include "GeckoProfiler.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
@ -824,8 +822,7 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
|||
|
||||
nsJSContext::nsJSContext(bool aGCOnDestruction,
|
||||
nsIScriptGlobalObject* aGlobalObject)
|
||||
: mWindowProxy(nullptr)
|
||||
, mGCOnDestruction(aGCOnDestruction)
|
||||
: mGCOnDestruction(aGCOnDestruction)
|
||||
, mGlobalObjectRef(aGlobalObject)
|
||||
{
|
||||
EnsureStatics();
|
||||
|
@ -839,8 +836,7 @@ nsJSContext::nsJSContext(bool aGCOnDestruction,
|
|||
|
||||
++sContextCount;
|
||||
|
||||
mDefaultJSOptions = JSOPTION_PRIVATE_IS_NSISUPPORTS |
|
||||
JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT;
|
||||
mDefaultJSOptions = JSOPTION_PRIVATE_IS_NSISUPPORTS;
|
||||
|
||||
mContext = ::JS_NewContext(sRuntime, gStackSize);
|
||||
if (mContext) {
|
||||
|
@ -859,7 +855,6 @@ nsJSContext::nsJSContext(bool aGCOnDestruction,
|
|||
mIsInitialized = false;
|
||||
mScriptsEnabled = true;
|
||||
mProcessingScriptTag = false;
|
||||
NS_HOLD_JS_OBJECTS(this, nsJSContext);
|
||||
}
|
||||
|
||||
nsJSContext::~nsJSContext()
|
||||
|
@ -910,14 +905,12 @@ nsJSContext::DestroyJSContext()
|
|||
|
||||
JS_DestroyContextNoGC(mContext);
|
||||
mContext = nullptr;
|
||||
NS_DROP_JS_OBJECTS(this, nsJSContext);
|
||||
}
|
||||
|
||||
// QueryInterface implementation for nsJSContext
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSContext)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsJSContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mWindowProxy)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSContext)
|
||||
|
@ -925,14 +918,18 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSContext)
|
|||
"Trying to unlink a context with outstanding requests.");
|
||||
tmp->mIsInitialized = false;
|
||||
tmp->mGCOnDestruction = false;
|
||||
tmp->mWindowProxy = nullptr;
|
||||
if (tmp->mContext) {
|
||||
JSAutoRequest ar(tmp->mContext);
|
||||
js::SetDefaultObjectForContext(tmp->mContext, nullptr);
|
||||
}
|
||||
tmp->DestroyJSContext();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobalObjectRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsJSContext)
|
||||
NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsJSContext, tmp->GetCCRefcnt())
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobalObjectRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mContext");
|
||||
nsContentUtils::XPConnect()->NoteJSContext(tmp->mContext, cb);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsJSContext)
|
||||
|
@ -1085,7 +1082,7 @@ nsIScriptGlobalObject *
|
|||
nsJSContext::GetGlobalObject()
|
||||
{
|
||||
AutoJSContext cx;
|
||||
JS::Rooted<JSObject*> global(mContext, GetWindowProxy());
|
||||
JS::Rooted<JSObject*> global(mContext, GetNativeGlobal());
|
||||
if (!global) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1134,10 +1131,16 @@ nsJSContext::GetGlobalObject()
|
|||
return sgo;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
nsJSContext::GetNativeGlobal()
|
||||
{
|
||||
return js::DefaultObjectForContextOrNull(mContext);
|
||||
}
|
||||
|
||||
JSContext*
|
||||
nsJSContext::GetNativeContext()
|
||||
{
|
||||
return mContext;
|
||||
return xpc_UnmarkGrayContext(mContext);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1177,7 +1180,7 @@ nsJSContext::SetProperty(JS::Handle<JSObject*> aTarget, const char* aPropName, n
|
|||
|
||||
Maybe<nsRootedJSValueArray> tempStorage;
|
||||
|
||||
JS::Rooted<JSObject*> global(mContext, GetWindowProxy());
|
||||
JS::Rooted<JSObject*> global(mContext, GetNativeGlobal());
|
||||
nsresult rv =
|
||||
ConvertSupportsTojsvals(aArgs, global, &argc, &argv, tempStorage);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -1473,7 +1476,7 @@ nsJSContext::AddSupportsPrimitiveTojsvals(nsISupports *aArg, JS::Value *aArgv)
|
|||
AutoFree iidGuard(iid); // Free iid upon destruction.
|
||||
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
|
||||
JS::Rooted<JSObject*> global(cx, GetWindowProxy());
|
||||
JS::Rooted<JSObject*> global(cx, xpc_UnmarkGrayObject(GetNativeGlobal()));
|
||||
JS::Rooted<JS::Value> v(cx);
|
||||
nsresult rv = nsContentUtils::WrapNative(cx, global,
|
||||
data, iid, v.address(),
|
||||
|
@ -2575,18 +2578,6 @@ nsJSContext::ReportPendingException()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsJSContext::SetWindowProxy(JS::Handle<JSObject*> aWindowProxy)
|
||||
{
|
||||
mWindowProxy = aWindowProxy;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
nsJSContext::GetWindowProxy()
|
||||
{
|
||||
return xpc_UnmarkGrayObject(mWindowProxy);
|
||||
}
|
||||
|
||||
void
|
||||
nsJSContext::LikelyShortLivingObjectCreated()
|
||||
{
|
||||
|
|
|
@ -19,7 +19,6 @@ class nsICycleCollectorListener;
|
|||
class nsIXPConnectJSObjectHolder;
|
||||
class nsRootedJSValueArray;
|
||||
class nsScriptNameSpaceManager;
|
||||
class nsCycleCollectionNoteRootCallback;
|
||||
|
||||
namespace mozilla {
|
||||
template <class> class Maybe;
|
||||
|
@ -54,6 +53,7 @@ public:
|
|||
inline nsIScriptGlobalObject *GetGlobalObjectRef() { return mGlobalObjectRef; }
|
||||
|
||||
virtual JSContext* GetNativeContext() MOZ_OVERRIDE;
|
||||
virtual JSObject* GetNativeGlobal() MOZ_OVERRIDE;
|
||||
virtual nsresult InitContext() MOZ_OVERRIDE;
|
||||
virtual bool IsContextInitialized() MOZ_OVERRIDE;
|
||||
|
||||
|
@ -70,9 +70,6 @@ public:
|
|||
virtual void WillInitializeContext() MOZ_OVERRIDE;
|
||||
virtual void DidInitializeContext() MOZ_OVERRIDE;
|
||||
|
||||
virtual void SetWindowProxy(JS::Handle<JSObject*> aWindowProxy) MOZ_OVERRIDE;
|
||||
virtual JSObject* GetWindowProxy() MOZ_OVERRIDE;
|
||||
|
||||
static void LoadStart();
|
||||
static void LoadEnd();
|
||||
|
||||
|
@ -128,7 +125,7 @@ public:
|
|||
{
|
||||
// Verify that we have a global so that this
|
||||
// does always return a null when GetGlobalObject() is null.
|
||||
JSObject* global = GetWindowProxy();
|
||||
JSObject* global = GetNativeGlobal();
|
||||
return global ? mGlobalObjectRef.get() : nullptr;
|
||||
}
|
||||
protected:
|
||||
|
@ -153,14 +150,12 @@ protected:
|
|||
// function will set aside the frame chain on mContext before
|
||||
// reporting.
|
||||
void ReportPendingException();
|
||||
|
||||
private:
|
||||
void DestroyJSContext();
|
||||
|
||||
nsrefcnt GetCCRefcnt();
|
||||
|
||||
JSContext *mContext;
|
||||
JS::Heap<JSObject*> mWindowProxy;
|
||||
|
||||
bool mIsInitialized;
|
||||
bool mScriptsEnabled;
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include "nsJSUtils.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIXPConnect.h"
|
||||
|
@ -141,11 +140,7 @@ nsJSUtils::ReportPendingException(JSContext *aContext)
|
|||
if (JS_IsExceptionPending(aContext)) {
|
||||
bool saved = JS_SaveFrameChain(aContext);
|
||||
{
|
||||
nsIScriptContext* scx = GetScriptContextFromJSContext(aContext);
|
||||
JS::Rooted<JSObject*> scope(aContext);
|
||||
scope = scx ? scx->GetWindowProxy()
|
||||
: js::DefaultObjectForContextOrNull(aContext);
|
||||
JSAutoCompartment ac(aContext, scope);
|
||||
JSAutoCompartment ac(aContext, js::DefaultObjectForContextOrNull(aContext));
|
||||
JS_ReportPendingException(aContext);
|
||||
}
|
||||
if (saved) {
|
||||
|
@ -292,19 +287,3 @@ nsJSUtils::EvaluateString(JSContext* aCx,
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return rv;
|
||||
}
|
||||
|
||||
//
|
||||
// nsDOMJSUtils.h
|
||||
//
|
||||
|
||||
JSObject* GetDefaultScopeFromJSContext(JSContext *cx)
|
||||
{
|
||||
// DOM JSContexts don't store their default compartment object on
|
||||
// the cx, so in those cases we need to fetch it via the scx
|
||||
// instead.
|
||||
nsIScriptContext *scx = GetScriptContextFromJSContext(cx);
|
||||
if (scx) {
|
||||
return scx->GetWindowProxy();
|
||||
}
|
||||
return js::DefaultObjectForContextOrNull(cx);
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ public:
|
|||
|
||||
AutoPushJSContext cx(sc->GetNativeContext());
|
||||
|
||||
JS::Rooted<JSObject*> global(cx, sc->GetWindowProxy());
|
||||
JS::Rooted<JSObject*> global(cx, sc->GetNativeGlobal());
|
||||
rv = nsContentUtils::WrapNative(cx, global, adapter, aValue);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Cannot create native object!");
|
||||
|
|
|
@ -135,7 +135,7 @@ ArchiveRequest::ReaderReady(nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList,
|
|||
AutoPushJSContext cx(sc->GetNativeContext());
|
||||
NS_ASSERTION(cx, "Failed to get a context!");
|
||||
|
||||
JS::Rooted<JSObject*> global(cx, sc->GetWindowProxy());
|
||||
JS::Rooted<JSObject*> global(cx, sc->GetNativeGlobal());
|
||||
NS_ASSERTION(global, "Failed to get global object!");
|
||||
|
||||
JSAutoCompartment ac(cx, global);
|
||||
|
|
|
@ -79,7 +79,7 @@ FileRequest::NotifyHelperCompleted(FileHelper* aFileHelper)
|
|||
|
||||
JS::Rooted<JS::Value> result(cx);
|
||||
|
||||
JS::Rooted<JSObject*> global(cx, sc->GetWindowProxy());
|
||||
JS::Rooted<JSObject*> global(cx, sc->GetNativeGlobal());
|
||||
NS_ASSERTION(global, "Failed to get global object!");
|
||||
|
||||
JSAutoCompartment ac(cx, global);
|
||||
|
|
|
@ -56,7 +56,7 @@ MobileMessageCallback::NotifySuccess(nsISupports *aMessage)
|
|||
AutoPushJSContext cx(scriptContext->GetNativeContext());
|
||||
NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
|
||||
|
||||
JS::Rooted<JSObject*> global(cx, scriptContext->GetWindowProxy());
|
||||
JS::Rooted<JSObject*> global(cx, scriptContext->GetNativeGlobal());
|
||||
NS_ENSURE_TRUE(global, NS_ERROR_FAILURE);
|
||||
|
||||
JSAutoCompartment ac(cx, global);
|
||||
|
|
|
@ -67,7 +67,7 @@ MobileMessageCursorCallback::NotifyCursorResult(nsISupports* aResult)
|
|||
AutoPushJSContext cx(scriptContext->GetNativeContext());
|
||||
NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
|
||||
|
||||
JS::Rooted<JSObject*> global(cx, scriptContext->GetWindowProxy());
|
||||
JS::Rooted<JSObject*> global(cx, scriptContext->GetNativeGlobal());
|
||||
NS_ENSURE_TRUE(global, NS_ERROR_FAILURE);
|
||||
|
||||
JSAutoCompartment ac(cx, global);
|
||||
|
|
|
@ -155,7 +155,7 @@ MobileMessageManager::Send(const JS::Value& aNumber_, const nsAString& aMessage,
|
|||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> global(cx, sc->GetWindowProxy());
|
||||
JS::Rooted<JSObject*> global(cx, sc->GetNativeGlobal());
|
||||
NS_ASSERTION(global, "Failed to get global object!");
|
||||
|
||||
JSAutoCompartment ac(cx, global);
|
||||
|
|
|
@ -831,7 +831,8 @@ public:
|
|||
// call to JS_SetGCParameter inside CreateJSContextForWorker.
|
||||
WorkerJSRuntime(WorkerPrivate* aWorkerPrivate)
|
||||
: CycleCollectedJSRuntime(WORKER_DEFAULT_RUNTIME_HEAPSIZE,
|
||||
JS_NO_HELPER_THREADS),
|
||||
JS_NO_HELPER_THREADS,
|
||||
false),
|
||||
mWorkerPrivate(aWorkerPrivate)
|
||||
{
|
||||
// We need to ensure that a JSContext outlives the cycle collector, and
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
|
||||
/* XXX DOM dependency */
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsDOMJSUtils.h"
|
||||
#include "SandboxPrivate.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
@ -1697,7 +1696,7 @@ NS_IMETHODIMP
|
|||
jsdContext::GetGlobalObject (jsdIValue **_rval)
|
||||
{
|
||||
ASSERT_VALID_EPHEMERAL;
|
||||
JSObject *glob = GetDefaultScopeFromJSContext(mJSCx);
|
||||
JSObject *glob = js::DefaultObjectForContextOrNull(mJSCx);
|
||||
JSDValue *jsdv = JSD_NewValue (mJSDCx, OBJECT_TO_JSVAL(glob));
|
||||
if (!jsdv)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
|
|
@ -2399,15 +2399,6 @@ JS_IsGCMarkingTracer(JSTracer *trc)
|
|||
return IS_GC_MARKING_TRACER(trc);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_IsMarkingGray(JSTracer *trc)
|
||||
{
|
||||
JS_ASSERT(JS_IsGCMarkingTracer(trc));
|
||||
return trc->callback == GCMarker::GrayCallback;
|
||||
}
|
||||
#endif
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_GC(JSRuntime *rt)
|
||||
{
|
||||
|
|
|
@ -1641,18 +1641,16 @@ JS_StringToVersion(const char *string);
|
|||
|
||||
/* JS_BIT(10) is currently unused. */
|
||||
|
||||
#define JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT JS_BIT(11) /* This JSContext does not use a
|
||||
default compartment object. Such
|
||||
an object will not be set implicitly,
|
||||
and attempts to get or set it will
|
||||
assert. */
|
||||
/* JS_BIT(11) is currently unused. */
|
||||
|
||||
#define JSOPTION_NO_SCRIPT_RVAL JS_BIT(12) /* A promise to the compiler
|
||||
that a null rval out-param
|
||||
will be passed to each call
|
||||
to JS_ExecuteScript. */
|
||||
|
||||
/* JS_BIT(13) is currently unused. */
|
||||
#define JSOPTION_UNROOTED_GLOBAL JS_BIT(13) /* The GC will not root the
|
||||
contexts' default compartment
|
||||
object, leaving that up to the
|
||||
embedding. */
|
||||
|
||||
#define JSOPTION_BASELINE JS_BIT(14) /* Baseline compiler. */
|
||||
|
||||
|
@ -2327,12 +2325,6 @@ JS_SetFinalizeCallback(JSRuntime *rt, JSFinalizeCallback cb);
|
|||
extern JS_PUBLIC_API(bool)
|
||||
JS_IsGCMarkingTracer(JSTracer *trc);
|
||||
|
||||
/* For assertions only. */
|
||||
#ifdef DEBUG
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_IsMarkingGray(JSTracer *trc);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* JS_IsAboutToBeFinalized checks if the given object is going to be finalized
|
||||
* at the end of the current GC. When called outside of the context of a GC,
|
||||
|
|
|
@ -1279,7 +1279,7 @@ JSContext::mark(JSTracer *trc)
|
|||
/* Stack frames and slots are traced by StackSpace::mark. */
|
||||
|
||||
/* Mark other roots-by-definition in the JSContext. */
|
||||
if (defaultCompartmentObject_)
|
||||
if (defaultCompartmentObject_ && !hasOption(JSOPTION_UNROOTED_GLOBAL))
|
||||
MarkObjectRoot(trc, &defaultCompartmentObject_, "default compartment object");
|
||||
if (isExceptionPending())
|
||||
MarkValueRoot(trc, &exception, "exception");
|
||||
|
|
|
@ -444,10 +444,7 @@ struct JSContext : public js::ExclusiveContext,
|
|||
public:
|
||||
inline void setDefaultCompartmentObject(JSObject *obj);
|
||||
inline void setDefaultCompartmentObjectIfUnset(JSObject *obj);
|
||||
JSObject *maybeDefaultCompartmentObject() const {
|
||||
JS_ASSERT(!hasOption(JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT));
|
||||
return defaultCompartmentObject_;
|
||||
}
|
||||
JSObject *maybeDefaultCompartmentObject() const { return defaultCompartmentObject_; }
|
||||
|
||||
/* Wrap cx->exception for the current compartment. */
|
||||
void wrapPendingException();
|
||||
|
|
|
@ -429,18 +429,14 @@ JSContext::setPendingException(js::Value v) {
|
|||
inline void
|
||||
JSContext::setDefaultCompartmentObject(JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(!hasOption(JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT));
|
||||
defaultCompartmentObject_ = obj;
|
||||
}
|
||||
|
||||
inline void
|
||||
JSContext::setDefaultCompartmentObjectIfUnset(JSObject *obj)
|
||||
{
|
||||
if (!hasOption(JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT) &&
|
||||
!defaultCompartmentObject_)
|
||||
{
|
||||
if (!defaultCompartmentObject_)
|
||||
setDefaultCompartmentObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
|
|
|
@ -769,6 +769,12 @@ js::ContextHasOutstandingRequests(const JSContext *cx)
|
|||
}
|
||||
#endif
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
js::HasUnrootedGlobal(const JSContext *cx)
|
||||
{
|
||||
return cx->hasOption(JSOPTION_UNROOTED_GLOBAL);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::SetActivityCallback(JSRuntime *rt, ActivityCallback cb, void *arg)
|
||||
{
|
||||
|
|
|
@ -674,6 +674,9 @@ JS_FRIEND_API(bool)
|
|||
ContextHasOutstandingRequests(const JSContext *cx);
|
||||
#endif
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
HasUnrootedGlobal(const JSContext *cx);
|
||||
|
||||
typedef void
|
||||
(* ActivityCallback)(void *arg, bool active);
|
||||
|
||||
|
|
|
@ -682,17 +682,12 @@ bool
|
|||
JSRuntime::initSelfHosting(JSContext *cx)
|
||||
{
|
||||
JS_ASSERT(!selfHostingGlobal_);
|
||||
|
||||
bool receivesDefaultObject = !cx->hasOption(JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT);
|
||||
RootedObject savedGlobal(cx, receivesDefaultObject
|
||||
? js::DefaultObjectForContextOrNull(cx)
|
||||
: NULL);
|
||||
RootedObject savedGlobal(cx, js::DefaultObjectForContextOrNull(cx));
|
||||
if (!(selfHostingGlobal_ = JS_NewGlobalObject(cx, &self_hosting_global_class,
|
||||
NULL, JS::DontFireOnNewGlobalHook)))
|
||||
return false;
|
||||
JSAutoCompartment ac(cx, selfHostingGlobal_);
|
||||
if (receivesDefaultObject)
|
||||
js::SetDefaultObjectForContext(cx, selfHostingGlobal_);
|
||||
js::SetDefaultObjectForContext(cx, selfHostingGlobal_);
|
||||
Rooted<GlobalObject*> shg(cx, &selfHostingGlobal_->as<GlobalObject>());
|
||||
/*
|
||||
* During initialization of standard classes for the self-hosting global,
|
||||
|
@ -761,8 +756,7 @@ JSRuntime::initSelfHosting(JSContext *cx)
|
|||
ok = Evaluate(cx, shg, options, src, srcLen, &rv);
|
||||
}
|
||||
JS_SetErrorReporter(cx, oldReporter);
|
||||
if (receivesDefaultObject)
|
||||
js::SetDefaultObjectForContext(cx, savedGlobal);
|
||||
js::SetDefaultObjectForContext(cx, savedGlobal);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,8 @@ class nsWrapperCache;
|
|||
native JSEqualityOp(JSEqualityOp);
|
||||
[ptr] native JSScriptPtr(JSScript);
|
||||
[ptr] native voidPtrPtr(void*);
|
||||
[ptr] native nsScriptObjectTracerPtr(nsScriptObjectTracer);
|
||||
[ref] native nsCCTraversalCallbackRef(nsCycleCollectionTraversalCallback);
|
||||
[ptr] native nsAXPCNativeCallContextPtr(nsAXPCNativeCallContext);
|
||||
[ptr] native nsWrapperCachePtr(nsWrapperCache);
|
||||
[ref] native JSCompartmentOptions(JS::CompartmentOptions);
|
||||
|
@ -63,6 +65,11 @@ interface nsIInterfaceInfo;
|
|||
interface nsIXPCSecurityManager;
|
||||
interface nsIPrincipal;
|
||||
|
||||
%{C++
|
||||
class nsCycleCollectionTraversalCallback;
|
||||
class nsScriptObjectTracer;
|
||||
%}
|
||||
|
||||
/***************************************************************************/
|
||||
[uuid(909e8641-7c54-4dff-9b94-ba631f057b33)]
|
||||
interface nsIXPConnectJSObjectHolder : nsISupports
|
||||
|
@ -291,7 +298,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports
|
|||
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
|
||||
%}
|
||||
|
||||
[uuid(c4d0187c-6a78-4bdf-9cd9-d218644b715a)]
|
||||
[uuid(0ebc00f0-f3ad-11e2-b778-0800200c9a66)]
|
||||
interface nsIXPConnect : nsISupports
|
||||
{
|
||||
%{ C++
|
||||
|
@ -559,6 +566,14 @@ interface nsIXPConnect : nsISupports
|
|||
in JSObjectPtr sandbox,
|
||||
in boolean returnStringOnly);
|
||||
|
||||
/**
|
||||
* Note aJSContext as a child to the cycle collector.
|
||||
* @param aJSContext The JSContext to note.
|
||||
* @param aCb The cycle collection traversal callback.
|
||||
*/
|
||||
[noscript,notxpcom] void noteJSContext(in JSContextPtr aJSContext,
|
||||
in nsCCTraversalCallbackRef aCb);
|
||||
|
||||
/**
|
||||
* Whether or not XPConnect should report all JS exceptions when returning
|
||||
* from JS into C++. False by default, although any value set in the
|
||||
|
|
|
@ -70,14 +70,10 @@ XPCJSContextStack::Push(JSContext *cx)
|
|||
// compartment that's same-origin with the current one, we can skip it.
|
||||
nsIScriptSecurityManager* ssm = XPCWrapper::GetSecurityManager();
|
||||
if ((e.cx == cx) && ssm) {
|
||||
// DOM JSContexts don't store their default compartment object on
|
||||
// the cx, so in those cases we need to fetch it via the scx
|
||||
// instead.
|
||||
RootedObject defaultScope(cx, GetDefaultScopeFromJSContext(cx));
|
||||
|
||||
RootedObject defaultGlobal(cx, js::DefaultObjectForContextOrNull(cx));
|
||||
nsIPrincipal *currentPrincipal =
|
||||
GetCompartmentPrincipal(js::GetContextCompartment(cx));
|
||||
nsIPrincipal *defaultPrincipal = GetObjectPrincipal(defaultScope);
|
||||
nsIPrincipal *defaultPrincipal = GetObjectPrincipal(defaultGlobal);
|
||||
bool equal = false;
|
||||
currentPrincipal->Equals(defaultPrincipal, &equal);
|
||||
if (equal) {
|
||||
|
|
|
@ -2860,7 +2860,7 @@ SourceHook(JSContext *cx, JS::Handle<JSScript*> script, jschar **src,
|
|||
}
|
||||
|
||||
XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
|
||||
: CycleCollectedJSRuntime(32L * 1024L * 1024L, JS_USE_HELPER_THREADS),
|
||||
: CycleCollectedJSRuntime(32L * 1024L * 1024L, JS_USE_HELPER_THREADS, true),
|
||||
mJSContextStack(new XPCJSContextStack()),
|
||||
mCallContext(nullptr),
|
||||
mAutoRoots(nullptr),
|
||||
|
|
|
@ -1152,7 +1152,7 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex,
|
|||
return retval;
|
||||
|
||||
XPCContext *xpcc = ccx.GetXPCContext();
|
||||
JSContext *cx = ccx.GetJSContext();
|
||||
JSContext *cx = xpc_UnmarkGrayContext(ccx.GetJSContext());
|
||||
|
||||
if (!cx || !xpcc || !IsReflectable(methodIndex))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
|
|
@ -124,14 +124,14 @@ AutoCxPusher::AutoCxPusher(JSContext* cx, bool allowNull)
|
|||
|
||||
// Enter a request and a compartment for the duration that the cx is on the
|
||||
// stack if non-null.
|
||||
//
|
||||
// NB: We call UnmarkGrayContext so that this can obsolete the need for the
|
||||
// old XPCAutoRequest as well.
|
||||
if (cx) {
|
||||
mAutoRequest.construct(cx);
|
||||
|
||||
// DOM JSContexts don't store their default compartment object on the cx.
|
||||
JSObject *compartmentObject = mScx ? mScx->GetWindowProxy()
|
||||
: js::DefaultObjectForContextOrNull(cx);
|
||||
if (compartmentObject)
|
||||
mAutoCompartment.construct(cx, compartmentObject);
|
||||
if (js::DefaultObjectForContextOrNull(cx))
|
||||
mAutoCompartment.construct(cx, js::DefaultObjectForContextOrNull(cx));
|
||||
xpc_UnmarkGrayContext(cx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -342,6 +342,14 @@ xpc_TryUnmarkWrappedGrayObject(nsISupports* aWrappedJS)
|
|||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
nsXPConnect::NoteJSContext(JSContext *aJSContext,
|
||||
nsCycleCollectionTraversalCallback &aCb)
|
||||
{
|
||||
aCb.NoteNativeChild(aJSContext, mozilla::CycleCollectedJSRuntime::JSContextParticipant());
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/***************************************************************************/
|
||||
// nsIXPConnect interface methods...
|
||||
|
@ -1315,7 +1323,8 @@ xpc_ActivateDebugMode()
|
|||
JSContext*
|
||||
nsXPConnect::GetCurrentJSContext()
|
||||
{
|
||||
return GetRuntime()->GetJSContextStack()->Peek();
|
||||
JSContext *cx = GetRuntime()->GetJSContextStack()->Peek();
|
||||
return xpc_UnmarkGrayContext(cx);
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
|
|
|
@ -162,6 +162,21 @@ xpc_UnmarkGrayScript(JSScript *script)
|
|||
return script;
|
||||
}
|
||||
|
||||
inline JSContext *
|
||||
xpc_UnmarkGrayContext(JSContext *cx)
|
||||
{
|
||||
if (cx) {
|
||||
JSObject *global = js::DefaultObjectForContextOrNull(cx);
|
||||
xpc_UnmarkGrayObject(global);
|
||||
if (global && JS_IsInRequest(JS_GetRuntime(cx))) {
|
||||
JSObject *scope = JS::CurrentGlobalOrNull(cx);
|
||||
if (scope != global)
|
||||
xpc_UnmarkGrayObject(scope);
|
||||
}
|
||||
}
|
||||
return cx;
|
||||
}
|
||||
|
||||
// If aVariant is an XPCVariant, this marks the object to be in aGeneration.
|
||||
// This also unmarks the gray JSObject.
|
||||
extern void
|
||||
|
|
|
@ -278,6 +278,47 @@ private:
|
|||
bool mAnyMarked;
|
||||
};
|
||||
|
||||
class JSContextParticipant : public nsCycleCollectionParticipant
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD Root(void *n)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD Unlink(void *n)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD Unroot(void *n)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD_(void) DeleteCycleCollectable(void *n)
|
||||
{
|
||||
}
|
||||
NS_IMETHOD Traverse(void *n, nsCycleCollectionTraversalCallback &cb)
|
||||
{
|
||||
JSContext *cx = static_cast<JSContext*>(n);
|
||||
|
||||
// JSContexts do not have an internal refcount and always have a single
|
||||
// owner (e.g., nsJSContext). Thus, the default refcount is 1. However,
|
||||
// in the (abnormal) case of synchronous cycle-collection, the context
|
||||
// may be actively executing code in which case we want to treat it as
|
||||
// rooted by adding an extra refcount.
|
||||
unsigned refCount = js::ContextHasOutstandingRequests(cx) ? 2 : 1;
|
||||
|
||||
cb.DescribeRefCountedNode(refCount, "JSContext");
|
||||
if (JSObject *global = js::DefaultObjectForContextOrNull(cx)) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "[global object]");
|
||||
cb.NoteJSChild(global);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
static JSContextParticipant JSContext_cycleCollectorGlobal;
|
||||
|
||||
struct Closure
|
||||
{
|
||||
bool cycleCollectionEnabled;
|
||||
|
@ -434,10 +475,12 @@ NoteJSChildGrayWrapperShim(void* aData, void* aThing)
|
|||
static const JSZoneParticipant sJSZoneCycleCollectorGlobal;
|
||||
|
||||
CycleCollectedJSRuntime::CycleCollectedJSRuntime(uint32_t aMaxbytes,
|
||||
JSUseHelperThreads aUseHelperThreads)
|
||||
JSUseHelperThreads aUseHelperThreads,
|
||||
bool aExpectUnrootedGlobals)
|
||||
: mGCThingCycleCollectorGlobal(sGCThingCycleCollectorGlobal),
|
||||
mJSZoneCycleCollectorGlobal(sJSZoneCycleCollectorGlobal),
|
||||
mJSRuntime(nullptr)
|
||||
mJSRuntime(nullptr),
|
||||
mExpectUnrootedGlobals(aExpectUnrootedGlobals)
|
||||
#ifdef DEBUG
|
||||
, mObjectToUnlink(nullptr)
|
||||
#endif
|
||||
|
@ -497,6 +540,23 @@ CycleCollectedJSRuntime::UnmarkSkippableJSHolders()
|
|||
mJSHolders.Enumerate(UnmarkJSHolder, nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
CycleCollectedJSRuntime::MaybeTraceGlobals(JSTracer* aTracer) const
|
||||
{
|
||||
JSContext* iter = nullptr;
|
||||
while (JSContext* acx = JS_ContextIterator(Runtime(), &iter)) {
|
||||
MOZ_ASSERT(js::HasUnrootedGlobal(acx) == mExpectUnrootedGlobals);
|
||||
if (!js::HasUnrootedGlobal(acx)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (JSObject* global = js::DefaultObjectForContextOrNull(acx)) {
|
||||
JS::AssertGCThingMustBeTenured(global);
|
||||
JS_CallObjectTracer(aTracer, &global, "Global Object");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CycleCollectedJSRuntime::DescribeGCThing(bool aIsMarked, void* aThing,
|
||||
JSGCTraceKind aTraceKind,
|
||||
|
@ -674,9 +734,32 @@ CycleCollectedJSRuntime::TraverseObjectShim(void* aData, void* aThing)
|
|||
JSTRACE_OBJECT, closure->cb);
|
||||
}
|
||||
|
||||
// For all JS objects that are held by native objects but aren't held
|
||||
// through rooting or locking, we need to add all the native objects that
|
||||
// hold them so that the JS objects are colored correctly in the cycle
|
||||
// collector. This includes JSContexts that don't have outstanding requests,
|
||||
// because their global object wasn't marked by the JS GC. All other JS
|
||||
// roots were marked by the JS GC and will be colored correctly in the cycle
|
||||
// collector.
|
||||
void
|
||||
CycleCollectedJSRuntime::MaybeTraverseGlobals(nsCycleCollectionNoteRootCallback& aCb) const
|
||||
{
|
||||
JSContext *iter = nullptr, *acx;
|
||||
while ((acx = JS_ContextIterator(Runtime(), &iter))) {
|
||||
// Add the context to the CC graph only if traversing it would
|
||||
// end up doing something.
|
||||
JSObject* global = js::DefaultObjectForContextOrNull(acx);
|
||||
if (global && xpc_IsGrayGCThing(global)) {
|
||||
aCb.NoteNativeRoot(acx, JSContextParticipant());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CycleCollectedJSRuntime::TraverseNativeRoots(nsCycleCollectionNoteRootCallback& aCb)
|
||||
{
|
||||
MaybeTraverseGlobals(aCb);
|
||||
|
||||
// NB: This is here just to preserve the existing XPConnect order. I doubt it
|
||||
// would hurt to do this after the JS holders.
|
||||
TraverseAdditionalNativeRoots(aCb);
|
||||
|
@ -756,6 +839,8 @@ TraceJSHolder(void* aHolder, nsScriptObjectTracer*& aTracer, void* aArg)
|
|||
void
|
||||
CycleCollectedJSRuntime::TraceNativeGrayRoots(JSTracer* aTracer)
|
||||
{
|
||||
MaybeTraceGlobals(aTracer);
|
||||
|
||||
// NB: This is here just to preserve the existing XPConnect order. I doubt it
|
||||
// would hurt to do this after the JS holders.
|
||||
TraceAdditionalNativeGrayRoots(aTracer);
|
||||
|
@ -831,6 +916,13 @@ CycleCollectedJSRuntime::AssertNoObjectsToTrace(void* aPossibleJSHolder)
|
|||
}
|
||||
#endif
|
||||
|
||||
// static
|
||||
nsCycleCollectionParticipant*
|
||||
CycleCollectedJSRuntime::JSContextParticipant()
|
||||
{
|
||||
return &JSContext_cycleCollectorGlobal;
|
||||
}
|
||||
|
||||
nsCycleCollectionParticipant*
|
||||
CycleCollectedJSRuntime::GCThingParticipant()
|
||||
{
|
||||
|
@ -880,18 +972,19 @@ CycleCollectedJSRuntime::UsefulToMergeZones() const
|
|||
JSContext* cx;
|
||||
JSAutoRequest ar(nsContentUtils::GetSafeJSContext());
|
||||
while ((cx = JS_ContextIterator(mJSRuntime, &iter))) {
|
||||
// Skip anything without an nsIScriptContext.
|
||||
// Skip anything without an nsIScriptContext, as well as any scx whose
|
||||
// NativeGlobal() is not an outer window (this happens with XUL Prototype
|
||||
// compilation scopes, for example, which we're not interested in).
|
||||
nsIScriptContext* scx = GetScriptContextFromJSContext(cx);
|
||||
JS::RootedObject obj(cx, scx ? scx->GetWindowProxy() : nullptr);
|
||||
if (!obj) {
|
||||
JS::RootedObject global(cx, scx ? scx->GetNativeGlobal() : nullptr);
|
||||
if (!global || !js::GetObjectParent(global)) {
|
||||
continue;
|
||||
}
|
||||
MOZ_ASSERT(js::IsOuterObject(obj));
|
||||
// Grab the inner from the outer.
|
||||
obj = JS_ObjectToInnerObject(cx, obj);
|
||||
MOZ_ASSERT(!js::GetObjectParent(obj));
|
||||
if (JS::GCThingIsMarkedGray(obj) &&
|
||||
!js::IsSystemCompartment(js::GetObjectCompartment(obj))) {
|
||||
global = JS_ObjectToInnerObject(cx, global);
|
||||
MOZ_ASSERT(!js::GetObjectParent(global));
|
||||
if (JS::GCThingIsMarkedGray(global) &&
|
||||
!js::IsSystemCompartment(js::GetObjectCompartment(global))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1094,7 +1187,21 @@ CycleCollectedJSRuntime::OnGC(JSGCStatus aStatus)
|
|||
{
|
||||
switch (aStatus) {
|
||||
case JSGC_BEGIN:
|
||||
{
|
||||
// XXXkhuey do we still need this?
|
||||
// We seem to sometime lose the unrooted global flag. Restore it
|
||||
// here. FIXME: bug 584495.
|
||||
if (mExpectUnrootedGlobals){
|
||||
JSContext* iter = nullptr;
|
||||
while (JSContext* acx = JS_ContextIterator(Runtime(), &iter)) {
|
||||
if (!js::HasUnrootedGlobal(acx)) {
|
||||
JS_ToggleOptions(acx, JSOPTION_UNROOTED_GLOBAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case JSGC_END:
|
||||
{
|
||||
/*
|
||||
|
@ -1123,5 +1230,11 @@ CycleCollectedJSRuntime::OnGC(JSGCStatus aStatus)
|
|||
bool
|
||||
CycleCollectedJSRuntime::OnContext(JSContext* aCx, unsigned aOperation)
|
||||
{
|
||||
if (mExpectUnrootedGlobals && aOperation == JSCONTEXT_NEW) {
|
||||
// XXXkhuey bholley is going to make this go away, but for now XPConnect
|
||||
// needs it.
|
||||
JS_ToggleOptions(aCx, JSOPTION_UNROOTED_GLOBAL);
|
||||
}
|
||||
|
||||
return CustomContextCallback(aCx, aOperation);
|
||||
}
|
||||
|
|
|
@ -83,7 +83,8 @@ class CycleCollectedJSRuntime
|
|||
friend class IncrementalFinalizeRunnable;
|
||||
protected:
|
||||
CycleCollectedJSRuntime(uint32_t aMaxbytes,
|
||||
JSUseHelperThreads aUseHelperThreads);
|
||||
JSUseHelperThreads aUseHelperThreads,
|
||||
bool aExpectUnrootedGlobals);
|
||||
virtual ~CycleCollectedJSRuntime();
|
||||
|
||||
JSRuntime* Runtime() const
|
||||
|
@ -148,8 +149,13 @@ private:
|
|||
static void
|
||||
TraverseObjectShim(void* aData, void* aThing);
|
||||
|
||||
void MaybeTraverseGlobals(nsCycleCollectionNoteRootCallback& aCb) const;
|
||||
|
||||
void TraverseNativeRoots(nsCycleCollectionNoteRootCallback& aCb);
|
||||
|
||||
void MaybeTraceGlobals(JSTracer* aTracer) const;
|
||||
|
||||
|
||||
static void TraceBlackJS(JSTracer* aTracer, void* aData);
|
||||
static void TraceGrayJS(JSTracer* aTracer, void* aData);
|
||||
static void GCCallback(JSRuntime* aRuntime, JSGCStatus aStatus, void* aData);
|
||||
|
@ -178,6 +184,9 @@ public:
|
|||
void AssertNoObjectsToTrace(void* aPossibleJSHolder);
|
||||
#endif
|
||||
|
||||
// This returns the singleton nsCycleCollectionParticipant for JSContexts.
|
||||
static nsCycleCollectionParticipant* JSContextParticipant();
|
||||
|
||||
nsCycleCollectionParticipant* GCThingParticipant();
|
||||
nsCycleCollectionParticipant* ZoneParticipant();
|
||||
|
||||
|
@ -215,6 +224,8 @@ private:
|
|||
|
||||
nsRefPtr<IncrementalFinalizeRunnable> mFinalizeRunnable;
|
||||
|
||||
bool mExpectUnrootedGlobals;
|
||||
|
||||
#ifdef DEBUG
|
||||
void* mObjectToUnlink;
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче