mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1233831 - Part 3: Install a callback to trace nursery collections; r=mccr8
This commit makes CycleCollectedJSRuntime install a nursery collection callback which traces nursery collections with a new `mozilla::TimelineMarker` subclass.
This commit is contained in:
parent
12fb783bb6
commit
7cc189e394
@ -58,11 +58,15 @@
|
||||
#include <algorithm>
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/AutoRestore.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Snprintf.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/TimelineConsumers.h"
|
||||
#include "mozilla/TimelineMarker.h"
|
||||
#include "mozilla/DebuggerOnGCRunnable.h"
|
||||
#include "mozilla/dom/DOMJSClass.h"
|
||||
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "jsprf.h"
|
||||
@ -411,6 +415,7 @@ CycleCollectedJSRuntime::CycleCollectedJSRuntime(JSRuntime* aParentRuntime,
|
||||
, mJSZoneCycleCollectorGlobal(sJSZoneCycleCollectorGlobal)
|
||||
, mJSRuntime(nullptr)
|
||||
, mPrevGCSliceCallback(nullptr)
|
||||
, mPrevGCNurseryCollectionCallback(nullptr)
|
||||
, mJSHolders(256)
|
||||
, mDoingStableStates(false)
|
||||
, mOutOfMemoryState(OOMState::OK)
|
||||
@ -437,6 +442,19 @@ CycleCollectedJSRuntime::CycleCollectedJSRuntime(JSRuntime* aParentRuntime,
|
||||
JS_SetGrayGCRootsTracer(mJSRuntime, TraceGrayJS, this);
|
||||
JS_SetGCCallback(mJSRuntime, GCCallback, this);
|
||||
mPrevGCSliceCallback = JS::SetGCSliceCallback(mJSRuntime, GCSliceCallback);
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
// We would like to support all threads here, but the way timeline consumers
|
||||
// are set up currently, you can either add a marker for one specific
|
||||
// docshell, or for every consumer globally. We would like to add a marker
|
||||
// for every consumer observing anything on this thread, but that is not
|
||||
// currently possible. For now, add global markers only when we are on the
|
||||
// main thread, since the UI for this tracing data only displays data
|
||||
// relevant to the main-thread.
|
||||
mPrevGCNurseryCollectionCallback = JS::SetGCNurseryCollectionCallback(
|
||||
mJSRuntime, GCNurseryCollectionCallback);
|
||||
}
|
||||
|
||||
JS_SetObjectsTenuredCallback(mJSRuntime, JSObjectsTenuredCb, this);
|
||||
JS::SetOutOfMemoryCallback(mJSRuntime, OutOfMemoryCallback, this);
|
||||
JS::SetLargeAllocationFailureCallback(mJSRuntime,
|
||||
@ -745,6 +763,76 @@ CycleCollectedJSRuntime::GCSliceCallback(JSRuntime* aRuntime,
|
||||
}
|
||||
}
|
||||
|
||||
class MinorGCMarker : public TimelineMarker
|
||||
{
|
||||
private:
|
||||
JS::gcreason::Reason mReason;
|
||||
|
||||
public:
|
||||
MinorGCMarker(MarkerTracingType aTracingType,
|
||||
JS::gcreason::Reason aReason)
|
||||
: TimelineMarker("MinorGC",
|
||||
aTracingType,
|
||||
MarkerStackRequest::NO_STACK)
|
||||
, mReason(aReason)
|
||||
{
|
||||
MOZ_ASSERT(aTracingType == MarkerTracingType::START ||
|
||||
aTracingType == MarkerTracingType::END);
|
||||
}
|
||||
|
||||
MinorGCMarker(JS::GCNurseryProgress aProgress,
|
||||
JS::gcreason::Reason aReason)
|
||||
: TimelineMarker("MinorGC",
|
||||
aProgress == JS::GCNurseryProgress::GC_NURSERY_COLLECTION_START
|
||||
? MarkerTracingType::START
|
||||
: MarkerTracingType::END,
|
||||
MarkerStackRequest::NO_STACK)
|
||||
, mReason(aReason)
|
||||
{ }
|
||||
|
||||
virtual void
|
||||
AddDetails(JSContext* aCx,
|
||||
dom::ProfileTimelineMarker& aMarker) override
|
||||
{
|
||||
TimelineMarker::AddDetails(aCx, aMarker);
|
||||
|
||||
if (GetTracingType() == MarkerTracingType::START) {
|
||||
auto reason = JS::gcreason::ExplainReason(mReason);
|
||||
aMarker.mCauseName.Construct(NS_ConvertUTF8toUTF16(reason));
|
||||
}
|
||||
}
|
||||
|
||||
virtual UniquePtr<AbstractTimelineMarker>
|
||||
Clone() override
|
||||
{
|
||||
auto clone = MakeUnique<MinorGCMarker>(GetTracingType(), mReason);
|
||||
clone->SetCustomTime(GetTime());
|
||||
return UniquePtr<AbstractTimelineMarker>(Move(clone));
|
||||
}
|
||||
};
|
||||
|
||||
/* static */ void
|
||||
CycleCollectedJSRuntime::GCNurseryCollectionCallback(JSRuntime* aRuntime,
|
||||
JS::GCNurseryProgress aProgress,
|
||||
JS::gcreason::Reason aReason)
|
||||
{
|
||||
CycleCollectedJSRuntime* self = CycleCollectedJSRuntime::Get();
|
||||
MOZ_ASSERT(self->Runtime() == aRuntime);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
|
||||
if (timelines && !timelines->IsEmpty()) {
|
||||
UniquePtr<AbstractTimelineMarker> abstractMarker(
|
||||
MakeUnique<MinorGCMarker>(aProgress, aReason));
|
||||
timelines->AddMarkerForAllObservedDocShells(abstractMarker);
|
||||
}
|
||||
|
||||
if (self->mPrevGCNurseryCollectionCallback) {
|
||||
self->mPrevGCNurseryCollectionCallback(aRuntime, aProgress, aReason);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* static */ void
|
||||
CycleCollectedJSRuntime::OutOfMemoryCallback(JSContext* aContext,
|
||||
void* aData)
|
||||
@ -1403,4 +1491,3 @@ CycleCollectedJSRuntime::OnLargeAllocationFailure()
|
||||
CustomLargeAllocationFailureCallback();
|
||||
AnnotateAndSetOutOfMemory(&mLargeAllocationFailureState, OOMState::Reported);
|
||||
}
|
||||
|
||||
|
@ -203,6 +203,9 @@ private:
|
||||
static void GCCallback(JSRuntime* aRuntime, JSGCStatus aStatus, void* aData);
|
||||
static void GCSliceCallback(JSRuntime* aRuntime, JS::GCProgress aProgress,
|
||||
const JS::GCDescription& aDesc);
|
||||
static void GCNurseryCollectionCallback(JSRuntime* aRuntime,
|
||||
JS::GCNurseryProgress aProgress,
|
||||
JS::gcreason::Reason aReason);
|
||||
static void OutOfMemoryCallback(JSContext* aContext, void* aData);
|
||||
static void LargeAllocationFailureCallback(void* aData);
|
||||
static bool ContextCallback(JSContext* aCx, unsigned aOperation,
|
||||
@ -341,6 +344,7 @@ private:
|
||||
JSRuntime* mJSRuntime;
|
||||
|
||||
JS::GCSliceCallback mPrevGCSliceCallback;
|
||||
JS::GCNurseryCollectionCallback mPrevGCNurseryCollectionCallback;
|
||||
|
||||
nsDataHashtable<nsPtrHashKey<void>, nsScriptObjectTracer*> mJSHolders;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user