Bug 677411 - Add telemetry counters for JS GC (r=luke)

This commit is contained in:
Bill McCloskey 2011-10-11 10:38:26 -07:00
parent 37073a57a3
commit acdb8bc2e3
7 changed files with 77 additions and 0 deletions

View File

@ -163,6 +163,16 @@ Statistics::endGC()
endPhase(PHASE_GC);
crash::SnapshotGCStack();
if (JSAccumulateTelemetryDataCallback cb = runtime->telemetryCallback) {
(*cb)(JS_TELEMETRY_GC_REASON, triggerReason);
(*cb)(JS_TELEMETRY_GC_IS_COMPARTMENTAL, compartment ? 1 : 0);
(*cb)(JS_TELEMETRY_GC_IS_SHAPE_REGEN,
runtime->shapeGen & SHAPE_OVERFLOW_BIT ? 1 : 0);
(*cb)(JS_TELEMETRY_GC_MS, t(PHASE_GC));
(*cb)(JS_TELEMETRY_GC_MARK_MS, t(PHASE_MARK));
(*cb)(JS_TELEMETRY_GC_SWEEP_MS, t(PHASE_SWEEP));
}
if (fp)
printStats();

View File

@ -705,6 +705,7 @@ JSRuntime::JSRuntime()
debuggerMutations(0),
securityCallbacks(NULL),
structuredCloneCallbacks(NULL),
telemetryCallback(NULL),
propertyRemovals(0),
scriptFilenameTable(NULL),
#ifdef JS_THREADSAFE

View File

@ -45,6 +45,7 @@
*/
#include <string.h>
#include "jsfriendapi.h"
#include "jsprvtd.h"
#include "jsatom.h"
#include "jsclist.h"
@ -604,6 +605,9 @@ struct JSRuntime {
/* Structured data callbacks are runtime-wide. */
const JSStructuredCloneCallbacks *structuredCloneCallbacks;
/* Call this to accumulate telemetry data. */
JSAccumulateTelemetryDataCallback telemetryCallback;
/*
* The propertyRemovals counter is incremented for every JSObject::clear,
* and for each JSObject::remove method call that frees a slot in the given

View File

@ -222,3 +222,9 @@ JS_GetCustomIteratorCount(JSContext *cx)
{
return sCustomIteratorCount;
}
JS_FRIEND_API(void)
JS_SetAccumulateTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback)
{
rt->telemetryCallback = callback;
}

View File

@ -79,6 +79,21 @@ JS_SetProtoCalled(JSContext *cx);
extern JS_FRIEND_API(size_t)
JS_GetCustomIteratorCount(JSContext *cx);
enum {
JS_TELEMETRY_GC_REASON,
JS_TELEMETRY_GC_IS_COMPARTMENTAL,
JS_TELEMETRY_GC_IS_SHAPE_REGEN,
JS_TELEMETRY_GC_MS,
JS_TELEMETRY_GC_MARK_MS,
JS_TELEMETRY_GC_SWEEP_MS
};
typedef void
(* JSAccumulateTelemetryDataCallback)(int id, JSUint32 sample);
extern JS_FRIEND_API(void)
JS_SetAccumulateTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback);
/* Data for tracking analysis/inference memory usage. */
typedef struct TypeInferenceMemoryStats
{

View File

@ -53,6 +53,7 @@
#include "mozilla/FunctionTimer.h"
#include "prsystem.h"
#include "mozilla/Preferences.h"
#include "mozilla/Telemetry.h"
#ifdef MOZ_CRASHREPORTER
#include "nsExceptionHandler.h"
@ -2017,6 +2018,31 @@ DiagnosticMemoryCallback(void *ptr, size_t size)
}
#endif
static void
AccumulateTelemetryCallback(int id, JSUint32 sample)
{
switch (id) {
case JS_TELEMETRY_GC_REASON:
Telemetry::Accumulate(Telemetry::GC_REASON, sample);
break;
case JS_TELEMETRY_GC_IS_COMPARTMENTAL:
Telemetry::Accumulate(Telemetry::GC_IS_COMPARTMENTAL, sample);
break;
case JS_TELEMETRY_GC_IS_SHAPE_REGEN:
Telemetry::Accumulate(Telemetry::GC_IS_SHAPE_REGEN, sample);
break;
case JS_TELEMETRY_GC_MS:
Telemetry::Accumulate(Telemetry::GC_MS, sample);
break;
case JS_TELEMETRY_GC_MARK_MS:
Telemetry::Accumulate(Telemetry::GC_MARK_MS, sample);
break;
case JS_TELEMETRY_GC_SWEEP_MS:
Telemetry::Accumulate(Telemetry::GC_SWEEP_MS, sample);
break;
}
}
bool XPCJSRuntime::gNewDOMBindingsEnabled;
XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
@ -2084,6 +2110,7 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
#ifdef MOZ_CRASHREPORTER
JS_EnumerateDiagnosticMemoryRegions(DiagnosticMemoryCallback);
#endif
JS_SetAccumulateTelemetryCallback(mJSRuntime, AccumulateTelemetryCallback);
mWatchdogWakeup = JS_NEW_CONDVAR(mJSRuntime->gcLock);
if (!mWatchdogWakeup)
NS_RUNTIMEABORT("JS_NEW_CONDVAR failed.");

View File

@ -56,10 +56,24 @@ HISTOGRAM(A11Y_INSTANTIATED, 0, 1, 2, BOOLEAN, "has accessibility support been i
HISTOGRAM(ISIMPLE_DOM_USAGE, 0, 1, 2, BOOLEAN, "have the ISimpleDOM* accessibility interfaces been used")
HISTOGRAM(IACCESSIBLE_TABLE_USAGE, 0, 1, 2, BOOLEAN, "has the IAccessibleTable accessibility interface been used")
/**
* Cycle collector telemetry
*/
HISTOGRAM(CYCLE_COLLECTOR, 1, 10000, 50, EXPONENTIAL, "Time spent on one cycle collection (ms)")
HISTOGRAM(CYCLE_COLLECTOR_VISITED_REF_COUNTED, 1, 300000, 50, EXPONENTIAL, "Number of ref counted objects visited by the cycle collector")
HISTOGRAM(CYCLE_COLLECTOR_VISITED_GCED, 1, 300000, 50, EXPONENTIAL, "Number of JS objects visited by the cycle collector")
HISTOGRAM(CYCLE_COLLECTOR_COLLECTED, 1, 100000, 50, EXPONENTIAL, "Number of objects collected by the cycle collector")
/**
* GC telemetry
*/
HISTOGRAM(GC_REASON, 0, 20, 20, LINEAR, "Reason (enum value) for initiating a GC")
HISTOGRAM(GC_IS_COMPARTMENTAL, 0, 1, 2, BOOLEAN, "Is it a compartmental GC?")
HISTOGRAM(GC_IS_SHAPE_REGEN, 0, 1, 2, BOOLEAN, "Is it a shape regenerating GC?")
HISTOGRAM(GC_MS, 1, 10000, 50, EXPONENTIAL, "Time spent running JS GC (ms)")
HISTOGRAM(GC_MARK_MS, 1, 10000, 50, EXPONENTIAL, "Time spent running JS GC mark phase (ms)")
HISTOGRAM(GC_SWEEP_MS, 1, 10000, 50, EXPONENTIAL, "Time spent running JS GC sweep phase (ms)")
HISTOGRAM(TELEMETRY_PING, 1, 3000, 10, EXPONENTIAL, "Time taken to submit telemetry info (ms)")
HISTOGRAM(TELEMETRY_SUCCESS, 0, 1, 2, BOOLEAN, "Successful telemetry submission")
HISTOGRAM(MEMORY_JS_COMPARTMENTS_SYSTEM, 1, 1000, 50, EXPONENTIAL, "Total JavaScript compartments used for add-ons and internals.")