зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1308039 - Add AutoAssertOnBarrier (r=jonco)
This commit is contained in:
Родитель
f5fb4df360
Коммит
b5679facbf
|
@ -520,6 +520,20 @@ class JS_PUBLIC_API(AutoAssertNoAlloc)
|
|||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Assert if a GC barrier is invoked while this class is live. This class does
|
||||
* not disable the static rooting hazard analysis.
|
||||
*/
|
||||
class JS_PUBLIC_API(AutoAssertOnBarrier)
|
||||
{
|
||||
JSContext* context;
|
||||
bool prev;
|
||||
|
||||
public:
|
||||
explicit AutoAssertOnBarrier(JSContext* cx);
|
||||
~AutoAssertOnBarrier();
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable the static rooting hazard analysis in the live region and assert if
|
||||
* any allocation that could potentially trigger a GC occurs while this guard
|
||||
|
@ -609,6 +623,7 @@ ExposeGCThingToActiveJS(JS::GCCellPtr thing)
|
|||
if (IsInsideNursery(thing.asCell()))
|
||||
return;
|
||||
JS::shadow::Runtime* rt = detail::GetGCThingRuntime(thing.unsafeAsUIntPtr());
|
||||
MOZ_DIAGNOSTIC_ASSERT(rt->allowGCBarriers());
|
||||
if (IsIncrementalBarrierNeededOnTenuredGCThing(rt, thing))
|
||||
JS::IncrementalReferenceBarrier(thing);
|
||||
else if (JS::GCThingIsMarkedGray(thing))
|
||||
|
@ -619,6 +634,7 @@ static MOZ_ALWAYS_INLINE void
|
|||
MarkGCThingAsLive(JSRuntime* aRt, JS::GCCellPtr thing)
|
||||
{
|
||||
JS::shadow::Runtime* rt = JS::shadow::Runtime::asShadowRuntime(aRt);
|
||||
MOZ_DIAGNOSTIC_ASSERT(rt->allowGCBarriers());
|
||||
/*
|
||||
* Any object in the nursery will not be freed during any GC running at that time.
|
||||
*/
|
||||
|
|
|
@ -7013,6 +7013,20 @@ JS::AutoAssertOnGC::~AutoAssertOnGC()
|
|||
}
|
||||
}
|
||||
|
||||
JS::AutoAssertOnBarrier::AutoAssertOnBarrier(JSContext* cx)
|
||||
: context(cx),
|
||||
prev(cx->runtime()->allowGCBarriers())
|
||||
{
|
||||
context->runtime()->allowGCBarriers_ = false;
|
||||
}
|
||||
|
||||
JS::AutoAssertOnBarrier::~AutoAssertOnBarrier()
|
||||
{
|
||||
MOZ_ASSERT(!context->runtime()->allowGCBarriers_);
|
||||
context->runtime()->allowGCBarriers_ = prev;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
JS::AutoAssertNoAlloc::AutoAssertNoAlloc(JSContext* cx)
|
||||
: gc(nullptr)
|
||||
{
|
||||
|
|
|
@ -131,6 +131,7 @@ class StoreBuffer;
|
|||
namespace JS {
|
||||
|
||||
class JS_PUBLIC_API(AutoEnterCycleCollection);
|
||||
class JS_PUBLIC_API(AutoAssertOnBarrier);
|
||||
struct PropertyDescriptor;
|
||||
|
||||
typedef void (*OffThreadCompileCallback)(void* token, void* callbackData);
|
||||
|
@ -153,11 +154,17 @@ struct Runtime
|
|||
friend class JS::AutoEnterCycleCollection;
|
||||
JS::HeapState heapState_;
|
||||
|
||||
// In some cases, invoking GC barriers (incremental or otherwise) will break
|
||||
// things. These barriers assert if this flag is set.
|
||||
bool allowGCBarriers_;
|
||||
friend class JS::AutoAssertOnBarrier;
|
||||
|
||||
js::gc::StoreBuffer* gcStoreBufferPtr_;
|
||||
|
||||
public:
|
||||
Runtime()
|
||||
: heapState_(JS::HeapState::Idle)
|
||||
, allowGCBarriers_(true)
|
||||
, gcStoreBufferPtr_(nullptr)
|
||||
{}
|
||||
|
||||
|
@ -169,6 +176,8 @@ struct Runtime
|
|||
return heapState_ == JS::HeapState::CycleCollecting;
|
||||
}
|
||||
|
||||
bool allowGCBarriers() const { return allowGCBarriers_; }
|
||||
|
||||
js::gc::StoreBuffer* gcStoreBufferPtr() { return gcStoreBufferPtr_; }
|
||||
|
||||
static JS::shadow::Runtime* asShadowRuntime(JSRuntime* rt) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче