зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1378717 - Speed up gray root buffering tracer by removing a virtual dispatch and some release asserts r=sfink
This commit is contained in:
Родитель
cb84415a1f
Коммит
b8dfe1df8d
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче