Bug 1308039 - Add AutoAssertOnBarrier (r=jonco)

This commit is contained in:
Bill McCloskey 2016-10-05 16:04:46 -07:00
Родитель f5fb4df360
Коммит b5679facbf
3 изменённых файлов: 39 добавлений и 0 удалений

Просмотреть файл

@ -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) {