Bug 730208 - UnmarkGray fixups for globals and contexts. r=billm

A common source of potential black -> gray edges is JSAPI calls made on objects with gray globals or contexts holding gray globals. (The call could potentially update a black object with a pointer to that global.) This patch mostly traps places where contexts are used, and unmarks their globals. It also includes some more global unmarking.

--HG--
extra : rebase_source : 835c1d6b4a7f7a11571412075ae8847475079edd
This commit is contained in:
Steve Fink 2012-03-14 09:32:58 -07:00
parent d62b8ed0a7
commit 2c59d5586c
5 changed files with 40 additions and 15 deletions

View File

@ -1827,7 +1827,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
return NS_ERROR_FAILURE;
}
JSAutoRequest ar(cx);
XPCAutoRequest ar(cx);
nsCOMPtr<WindowStateHolder> wsh = do_QueryInterface(aState);
NS_ASSERTION(!aState || wsh, "What kind of weird state are you giving me here?");

View File

@ -1244,7 +1244,7 @@ nsJSContext::EvaluateStringWithValue(const nsAString& aScript,
// check it isn't JSVERSION_UNKNOWN.
if (ok && ((JSVersion)aVersion) != JSVERSION_UNKNOWN) {
JSAutoRequest ar(mContext);
XPCAutoRequest ar(mContext);
JSAutoEnterCompartment ac;
if (!ac.enter(mContext, aScopeObject)) {
@ -1447,7 +1447,7 @@ nsJSContext::EvaluateString(const nsAString& aScript,
// Since the caller is responsible for parsing the version strings, we just
// check it isn't JSVERSION_UNKNOWN.
if (ok && JSVersion(aVersion) != JSVERSION_UNKNOWN) {
JSAutoRequest ar(mContext);
XPCAutoRequest ar(mContext);
JSAutoEnterCompartment ac;
if (!ac.enter(mContext, aScopeObject)) {
stack->Pop(nsnull);
@ -1471,7 +1471,7 @@ nsJSContext::EvaluateString(const nsAString& aScript,
// If all went well, convert val to a string if one is wanted.
if (ok) {
JSAutoRequest ar(mContext);
XPCAutoRequest ar(mContext);
JSAutoEnterCompartment ac;
if (!ac.enter(mContext, aScopeObject)) {
stack->Pop(nsnull);
@ -1533,7 +1533,8 @@ nsJSContext::CompileScript(const PRUnichar* aText,
if (!ok || JSVersion(aVersion) == JSVERSION_UNKNOWN)
return NS_OK;
JSAutoRequest ar(mContext);
XPCAutoRequest ar(mContext);
JSScript* script =
::JS_CompileUCScriptForPrincipalsVersion(mContext,
@ -1598,7 +1599,7 @@ nsJSContext::ExecuteScript(JSScript* aScriptObject,
NS_ENSURE_SUCCESS(rv, rv);
nsJSContext::TerminationFuncHolder holder(this);
JSAutoRequest ar(mContext);
XPCAutoRequest ar(mContext);
++mExecuteDepth;
// The result of evaluation, used only if there were no errors. This need
@ -1726,7 +1727,7 @@ nsJSContext::CompileEventHandler(nsIAtom *aName,
// Event handlers are always shared, and must be bound before use.
// Therefore we never bother compiling with principals.
// (that probably means we should avoid JS_CompileUCFunctionForPrincipals!)
JSAutoRequest ar(mContext);
XPCAutoRequest ar(mContext);
JSFunction* fun =
::JS_CompileUCFunctionForPrincipalsVersion(mContext,
@ -1789,7 +1790,7 @@ nsJSContext::CompileFunction(JSObject* aTarget,
JSObject *target = aTarget;
JSAutoRequest ar(mContext);
XPCAutoRequest ar(mContext);
JSFunction* fun =
::JS_CompileUCFunctionForPrincipalsVersion(mContext,
@ -1834,10 +1835,10 @@ nsJSContext::CallEventHandler(nsISupports* aTarget, JSObject* aScope,
SAMPLE_LABEL("JS", "CallEventHandler");
nsAutoMicroTask mt;
JSAutoRequest ar(mContext);
xpc_UnmarkGrayObject(aScope);
xpc_UnmarkGrayObject(aHandler);
XPCAutoRequest ar(mContext);
JSObject* target = nsnull;
nsresult rv = JSObjectFromInterface(aTarget, aScope, &target);
NS_ENSURE_SUCCESS(rv, rv);
@ -1946,10 +1947,10 @@ nsJSContext::BindCompiledEventHandler(nsISupports* aTarget, JSObject* aScope,
NS_ENSURE_TRUE(mIsInitialized, NS_ERROR_NOT_INITIALIZED);
NS_PRECONDITION(!aBoundHandler, "Shouldn't already have a bound handler!");
JSAutoRequest ar(mContext);
xpc_UnmarkGrayObject(aScope);
xpc_UnmarkGrayObject(aHandler);
XPCAutoRequest ar(mContext);
// Get the jsobject associated with this target
JSObject *target = nsnull;
@ -2106,7 +2107,7 @@ nsJSContext::CreateNativeGlobalForInner(
JSContext*
nsJSContext::GetNativeContext()
{
return mContext;
return xpc_UnmarkGrayContext(mContext);
}
nsresult
@ -2152,7 +2153,7 @@ nsJSContext::SetProperty(JSObject* aTarget, const char* aPropName, nsISupports*
PRUint32 argc;
jsval *argv = nsnull;
JSAutoRequest ar(mContext);
XPCAutoRequest ar(mContext);
Maybe<nsRootedJSValueArray> tempStorage;

View File

@ -1189,7 +1189,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;

View File

@ -2364,7 +2364,7 @@ nsXPConnect::Peek(JSContext * *_retval)
return NS_ERROR_FAILURE;
}
*_retval = data->GetJSContextStack()->Peek();
*_retval = xpc_UnmarkGrayContext(data->GetJSContextStack()->Peek());
return NS_OK;
}
@ -2469,7 +2469,7 @@ nsXPConnect::Pop(JSContext * *_retval)
JSContext *cx = data->GetJSContextStack()->Pop();
if (_retval)
*_retval = cx;
*_retval = xpc_UnmarkGrayContext(cx);
return NS_OK;
}

View File

@ -198,6 +198,30 @@ xpc_UnmarkGrayScript(JSScript *script)
return script;
}
inline JSContext *
xpc_UnmarkGrayContext(JSContext *cx)
{
if (cx) {
JSObject *global = JS_GetGlobalObject(cx);
xpc_UnmarkGrayObject(global);
if (JS_IsInRequest(JS_GetRuntime(cx))) {
JSObject *scope = JS_GetGlobalForScopeChain(cx);
if (scope != global)
xpc_UnmarkGrayObject(scope);
}
}
return cx;
}
#ifdef __cplusplus
class XPCAutoRequest : public JSAutoRequest {
public:
XPCAutoRequest(JSContext *cx) : JSAutoRequest(cx) {
xpc_UnmarkGrayContext(cx);
}
};
#endif
// If aVariant is an XPCVariant, this marks the object to be in aGeneration.
// This also unmarks the gray JSObject.
extern void