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:
Ryan VanderMeulen 2013-08-27 21:14:54 -04:00
Родитель 6349254839
Коммит 6f0d3838c9
33 изменённых файлов: 254 добавлений и 150 удалений

Просмотреть файл

@ -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