зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
024cd3a8e5
Коммит
66c30c5ec8
|
@ -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) \
|
||||
|
|
Загрузка…
Ссылка в новой задаче