Bug 834732 - Introduce AutoPushJSContext. r=mrbkap

It's annoying to add yet another RAII class, but we're solving a different
problem here. In particular, there are lots of callers that grab a cx off
of an nsIScriptContext and use it without pushing. Most of the time this
is ok, since that cx is also the active cx. But it's hard to tell when we
might potentially violate that invariant. What's more, we don't want to just
use an nsCxPusher, because that does expensive things even when the cx matches
the one on the top of the stack. Most of these consumers should just switch
to AutoJSContext, but doing such a change en masse is a pretty risky thing to
do. So let's introduce a class that gives us good performance in the common case
and correctness in the uncommon case.
This commit is contained in:
Bobby Holley 2013-02-26 11:04:12 -08:00
parent 65edc090d7
commit 9e96be0f79

View File

@ -2302,6 +2302,33 @@ public:
SafeAutoJSContext(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
};
/**
* Use AutoPushJSContext when you want to use a specific JSContext that may or
* may not be already on the stack. This differs from nsCxPusher in that it only
* pushes in the case that the given cx is not the active cx on the JSContext
* stack, which avoids an expensive JS_SaveFrameChain in the common case.
*
* Most consumers of this should probably just use AutoJSContext. But the goal
* here is to preserve the existing behavior while ensure proper cx-stack
* semantics in edge cases where the context being used doesn't match the active
* context.
*
* NB: This will not push a null cx even if aCx is null. Make sure you know what
* you're doing.
*/
class NS_STACK_CLASS AutoPushJSContext {
nsCxPusher mPusher;
JSContext* mCx;
public:
AutoPushJSContext(JSContext* aCx) : mCx(aCx) {
if (mCx && mCx != nsContentUtils::GetCurrentJSContext()) {
mPusher.Push(mCx);
}
}
operator JSContext*() { return mCx; }
};
} // namespace mozilla
#define NS_INTERFACE_MAP_ENTRY_TEAROFF(_interface, _allocator) \