Bug 1378717 - Speed up gray root buffering tracer by removing a virtual dispatch and some release asserts r=sfink

This commit is contained in:
Jon Coppeard 2017-07-11 16:51:26 +01:00
Родитель cb84415a1f
Коммит b8dfe1df8d
1 изменённых файлов: 18 добавлений и 15 удалений

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

@ -442,12 +442,21 @@ js::gc::GCRuntime::finishRoots()
// Append traced things to a buffer on the zone for use later in the GC.
// See the comment in GCRuntime.h above grayBufferState for details.
class BufferGrayRootsTracer : public JS::CallbackTracer
class BufferGrayRootsTracer final : public JS::CallbackTracer
{
// Set to false if we OOM while buffering gray roots.
bool bufferingGrayRootsFailed;
void onChild(const JS::GCCellPtr& thing) override;
void onObjectEdge(JSObject** objp) override { bufferRoot(*objp); }
void onStringEdge(JSString** stringp) override { bufferRoot(*stringp); }
void onScriptEdge(JSScript** scriptp) override { bufferRoot(*scriptp); }
void onSymbolEdge(JS::Symbol** symbolp) override { bufferRoot(*symbolp); }
void onChild(const JS::GCCellPtr& thing) override {
MOZ_CRASH("Unexpected gray root kind");
}
template <typename T> inline void bufferRoot(T* thing);
public:
explicit BufferGrayRootsTracer(JSRuntime* rt)
@ -494,22 +503,16 @@ js::gc::GCRuntime::bufferGrayRoots()
}
}
struct SetMaybeAliveFunctor {
template <typename T> void operator()(T* t) { SetMaybeAliveFlag(t); }
};
void
BufferGrayRootsTracer::onChild(const JS::GCCellPtr& thing)
template <typename T>
inline void
BufferGrayRootsTracer::bufferRoot(T* thing)
{
MOZ_ASSERT(JS::CurrentThreadIsHeapBusy());
MOZ_RELEASE_ASSERT(thing);
MOZ_ASSERT(thing);
// Check if |thing| is corrupt by calling a method that touches the heap.
MOZ_RELEASE_ASSERT(thing.asCell()->getTraceKind() <= JS::TraceKind::Null);
MOZ_ASSERT(thing->getTraceKind() <= JS::TraceKind::Null);
if (bufferingGrayRootsFailed)
return;
gc::TenuredCell* tenured = gc::TenuredCell::fromPointer(thing.asCell());
TenuredCell* tenured = &thing->asTenured();
// This is run from a helper thread while the mutator is paused so we have
// to use *FromAnyThread methods here.
@ -519,7 +522,7 @@ BufferGrayRootsTracer::onChild(const JS::GCCellPtr& thing)
// objects and scripts. We rely on gray root buffering for this to work,
// but we only need to worry about uncollected dead compartments during
// incremental GCs (when we do gray root buffering).
DispatchTyped(SetMaybeAliveFunctor(), thing);
SetMaybeAliveFlag(thing);
if (!zone->gcGrayRoots().append(tenured))
bufferingGrayRootsFailed = true;