зеркало из https://github.com/mozilla/gecko-dev.git
Bug 848449 - GC: Remove AutoAssertNoGC and AssertCanGC - Remove AutoAssertNoGC and AssertCanGC r=terrence
--HG-- extra : rebase_source : b2afa454a539be84db7a3b11eb7c776bf4054b07
This commit is contained in:
Родитель
3f97c69827
Коммит
21c7dfb5df
|
@ -83,17 +83,6 @@
|
||||||
* - Pass Handle<T> through your hot call stack to avoid re-rooting costs at
|
* - Pass Handle<T> through your hot call stack to avoid re-rooting costs at
|
||||||
* every invocation.
|
* every invocation.
|
||||||
*
|
*
|
||||||
* If this is not enough, the following family of two classes and two
|
|
||||||
* functions can provide partially type-safe and mostly runtime-safe access to
|
|
||||||
* GC things.
|
|
||||||
*
|
|
||||||
* - AutoAssertNoGC is a scoped guard that will trigger an assertion if a GC,
|
|
||||||
* or an appropriately marked method that might GC, is entered when it is in
|
|
||||||
* scope. By convention the name given to instances of this guard is |nogc|.
|
|
||||||
*
|
|
||||||
* - AssertCanGC() will assert if an AutoAssertNoGC is in scope either locally
|
|
||||||
* or anywhere in the call stack.
|
|
||||||
*
|
|
||||||
* There also exists a set of RawT typedefs for modules without rooting
|
* There also exists a set of RawT typedefs for modules without rooting
|
||||||
* concerns, such as the GC. Do not use these as they provide no rooting
|
* concerns, such as the GC. Do not use these as they provide no rooting
|
||||||
* protection whatsoever.
|
* protection whatsoever.
|
||||||
|
@ -135,16 +124,10 @@ namespace JS {
|
||||||
|
|
||||||
template <typename T> class Rooted;
|
template <typename T> class Rooted;
|
||||||
|
|
||||||
class AutoAssertNoGC;
|
|
||||||
|
|
||||||
template <typename T> class Handle;
|
template <typename T> class Handle;
|
||||||
template <typename T> class MutableHandle;
|
template <typename T> class MutableHandle;
|
||||||
|
|
||||||
JS_FRIEND_API(void) EnterAssertNoGCScope();
|
/* This is exposing internal state of the GC for inlining purposes. */
|
||||||
JS_FRIEND_API(void) LeaveAssertNoGCScope();
|
|
||||||
|
|
||||||
/* These are exposing internal state of the GC for inlining purposes. */
|
|
||||||
JS_FRIEND_API(bool) InNoGCScope();
|
|
||||||
JS_FRIEND_API(bool) isGCEnabled();
|
JS_FRIEND_API(bool) isGCEnabled();
|
||||||
|
|
||||||
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||||
|
@ -782,39 +765,6 @@ MutableHandle<T>::MutableHandle(Rooted<T> *root)
|
||||||
ptr = root->address();
|
ptr = root->address();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The scoped guard object AutoAssertNoGC forces the GC to assert if a GC is
|
|
||||||
* attempted while the guard object is live. If you have a GC-unsafe operation
|
|
||||||
* to perform, use this guard object to protect your operation.
|
|
||||||
*/
|
|
||||||
class AutoAssertNoGC
|
|
||||||
{
|
|
||||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
|
||||||
|
|
||||||
public:
|
|
||||||
AutoAssertNoGC(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) {
|
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
|
||||||
#ifdef DEBUG
|
|
||||||
EnterAssertNoGCScope();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
~AutoAssertNoGC() {
|
|
||||||
#ifdef DEBUG
|
|
||||||
LeaveAssertNoGCScope();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AssertCanGC will assert if it is called inside of an AutoAssertNoGC region.
|
|
||||||
*/
|
|
||||||
JS_ALWAYS_INLINE void
|
|
||||||
AssertCanGC()
|
|
||||||
{
|
|
||||||
JS_ASSERT_IF(isGCEnabled(), !InNoGCScope());
|
|
||||||
}
|
|
||||||
|
|
||||||
JS_FRIEND_API(bool) NeedRelaxedRootChecks();
|
JS_FRIEND_API(bool) NeedRelaxedRootChecks();
|
||||||
|
|
||||||
} /* namespace JS */
|
} /* namespace JS */
|
||||||
|
@ -827,7 +777,6 @@ namespace js {
|
||||||
*/
|
*/
|
||||||
inline void MaybeCheckStackRoots(JSContext *cx, bool relax = true)
|
inline void MaybeCheckStackRoots(JSContext *cx, bool relax = true)
|
||||||
{
|
{
|
||||||
JS::AssertCanGC();
|
|
||||||
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
|
||||||
if (relax && NeedRelaxedRootChecks())
|
if (relax && NeedRelaxedRootChecks())
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -217,17 +217,6 @@ JS::CheckStackRoots(JSContext *cx)
|
||||||
if (rt->gcZeal_ != ZealStackRootingValue)
|
if (rt->gcZeal_ != ZealStackRootingValue)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If this assertion fails, it means that an AutoAssertNoGC was placed
|
|
||||||
// around code that could trigger GC, and is therefore wrong. The
|
|
||||||
// AutoAssertNoGC should be removed and the code it was guarding should be
|
|
||||||
// modified to properly root any gcthings, and very possibly any code
|
|
||||||
// calling that function should also be modified if it was improperly
|
|
||||||
// assuming that GC could not happen at all within the called function.
|
|
||||||
// (The latter may not apply if the AutoAssertNoGC only protected a portion
|
|
||||||
// of a function, so the callers were already assuming that GC could
|
|
||||||
// happen.)
|
|
||||||
JS_ASSERT(!InNoGCScope());
|
|
||||||
|
|
||||||
// GCs can't happen when analysis/inference/compilation are active.
|
// GCs can't happen when analysis/inference/compilation are active.
|
||||||
if (cx->compartment->activeAnalysis)
|
if (cx->compartment->activeAnalysis)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -666,25 +666,6 @@ static JSBool js_NewRuntimeWasCalled = JS_FALSE;
|
||||||
mozilla::ThreadLocal<PerThreadData *> js::TlsPerThreadData;
|
mozilla::ThreadLocal<PerThreadData *> js::TlsPerThreadData;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
JS_FRIEND_API(void)
|
|
||||||
JS::EnterAssertNoGCScope()
|
|
||||||
{
|
|
||||||
++TlsPerThreadData.get()->gcAssertNoGCDepth;
|
|
||||||
}
|
|
||||||
|
|
||||||
JS_FRIEND_API(void)
|
|
||||||
JS::LeaveAssertNoGCScope()
|
|
||||||
{
|
|
||||||
--TlsPerThreadData.get()->gcAssertNoGCDepth;
|
|
||||||
JS_ASSERT(TlsPerThreadData.get()->gcAssertNoGCDepth >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
JS_FRIEND_API(bool)
|
|
||||||
JS::InNoGCScope()
|
|
||||||
{
|
|
||||||
return TlsPerThreadData.get()->gcAssertNoGCDepth > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
JS_FRIEND_API(bool)
|
JS_FRIEND_API(bool)
|
||||||
JS::isGCEnabled()
|
JS::isGCEnabled()
|
||||||
{
|
{
|
||||||
|
@ -697,9 +678,6 @@ JS::NeedRelaxedRootChecks()
|
||||||
return TlsPerThreadData.get()->gcRelaxRootChecks;
|
return TlsPerThreadData.get()->gcRelaxRootChecks;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
JS_FRIEND_API(void) JS::EnterAssertNoGCScope() {}
|
|
||||||
JS_FRIEND_API(void) JS::LeaveAssertNoGCScope() {}
|
|
||||||
JS_FRIEND_API(bool) JS::InNoGCScope() { return false; }
|
|
||||||
JS_FRIEND_API(bool) JS::isGCEnabled() { return true; }
|
JS_FRIEND_API(bool) JS::isGCEnabled() { return true; }
|
||||||
JS_FRIEND_API(bool) JS::NeedRelaxedRootChecks() { return false; }
|
JS_FRIEND_API(bool) JS::NeedRelaxedRootChecks() { return false; }
|
||||||
#endif
|
#endif
|
||||||
|
@ -711,7 +689,6 @@ js::PerThreadData::PerThreadData(JSRuntime *runtime)
|
||||||
runtime_(runtime),
|
runtime_(runtime),
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
gcRelaxRootChecks(false),
|
gcRelaxRootChecks(false),
|
||||||
gcAssertNoGCDepth(0),
|
|
||||||
#endif
|
#endif
|
||||||
ionTop(NULL),
|
ionTop(NULL),
|
||||||
ionJSContext(NULL),
|
ionJSContext(NULL),
|
||||||
|
|
|
@ -465,7 +465,6 @@ class PerThreadData : public js::PerThreadDataFriendFields
|
||||||
js::Vector<SavedGCRoot, 0, js::SystemAllocPolicy> gcSavedRoots;
|
js::Vector<SavedGCRoot, 0, js::SystemAllocPolicy> gcSavedRoots;
|
||||||
|
|
||||||
bool gcRelaxRootChecks;
|
bool gcRelaxRootChecks;
|
||||||
int gcAssertNoGCDepth;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2194,7 +2193,7 @@ class AutoObjectHashSet : public AutoHashSetRooter<RawObject>
|
||||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||||
};
|
};
|
||||||
|
|
||||||
class AutoAssertNoGCOrException : public AutoAssertNoGC
|
class AutoAssertNoException
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
JSContext *cx;
|
JSContext *cx;
|
||||||
|
@ -2202,7 +2201,7 @@ class AutoAssertNoGCOrException : public AutoAssertNoGC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AutoAssertNoGCOrException(JSContext *cx)
|
AutoAssertNoException(JSContext *cx)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
: cx(cx),
|
: cx(cx),
|
||||||
hadException(cx->isExceptionPending())
|
hadException(cx->isExceptionPending())
|
||||||
|
@ -2210,7 +2209,7 @@ class AutoAssertNoGCOrException : public AutoAssertNoGC
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~AutoAssertNoGCOrException()
|
~AutoAssertNoException()
|
||||||
{
|
{
|
||||||
JS_ASSERT_IF(!hadException, !cx->isExceptionPending());
|
JS_ASSERT_IF(!hadException, !cx->isExceptionPending());
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
#include "js/TemplateLib.h"
|
#include "js/TemplateLib.h"
|
||||||
#include "vm/Shape.h"
|
#include "vm/Shape.h"
|
||||||
|
|
||||||
using JS::AssertCanGC;
|
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
class Shape;
|
class Shape;
|
||||||
|
|
|
@ -1094,13 +1094,11 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode)
|
||||||
|
|
||||||
#define SET_SCRIPT(s) \
|
#define SET_SCRIPT(s) \
|
||||||
JS_BEGIN_MACRO \
|
JS_BEGIN_MACRO \
|
||||||
EnterAssertNoGCScope(); \
|
|
||||||
script = (s); \
|
script = (s); \
|
||||||
if (script->hasAnyBreakpointsOrStepMode() || script->hasScriptCounts) \
|
if (script->hasAnyBreakpointsOrStepMode() || script->hasScriptCounts) \
|
||||||
interrupts.enable(); \
|
interrupts.enable(); \
|
||||||
JS_ASSERT_IF(interpMode == JSINTERP_SKIP_TRAP, \
|
JS_ASSERT_IF(interpMode == JSINTERP_SKIP_TRAP, \
|
||||||
script->hasAnyBreakpointsOrStepMode()); \
|
script->hasAnyBreakpointsOrStepMode()); \
|
||||||
LeaveAssertNoGCScope(); \
|
|
||||||
JS_END_MACRO
|
JS_END_MACRO
|
||||||
|
|
||||||
/* Repoint cx->regs to a local variable for faster access. */
|
/* Repoint cx->regs to a local variable for faster access. */
|
||||||
|
|
|
@ -3584,7 +3584,7 @@ bool
|
||||||
js::LookupNameNoGC(JSContext *cx, PropertyName *name, JSObject *scopeChain,
|
js::LookupNameNoGC(JSContext *cx, PropertyName *name, JSObject *scopeChain,
|
||||||
JSObject **objp, JSObject **pobjp, Shape **propp)
|
JSObject **objp, JSObject **pobjp, Shape **propp)
|
||||||
{
|
{
|
||||||
AutoAssertNoGCOrException nogc(cx);
|
AutoAssertNoException nogc(cx);
|
||||||
|
|
||||||
JS_ASSERT(!*objp && !*pobjp && !*propp);
|
JS_ASSERT(!*objp && !*pobjp && !*propp);
|
||||||
|
|
||||||
|
@ -3862,7 +3862,7 @@ baseops::GetProperty(JSContext *cx, HandleObject obj, HandleObject receiver, Han
|
||||||
JSBool
|
JSBool
|
||||||
baseops::GetPropertyNoGC(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
|
baseops::GetPropertyNoGC(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp)
|
||||||
{
|
{
|
||||||
AutoAssertNoGCOrException nogc(cx);
|
AutoAssertNoException nogc(cx);
|
||||||
return GetPropertyHelperInline<NoGC>(cx, obj, receiver, id, 0, vp);
|
return GetPropertyHelperInline<NoGC>(cx, obj, receiver, id, 0, vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче