Bug 1080212 - [e10s] Add Telemetry probe for js exceptions that occur in the addon js compartment.r=billm

This commit is contained in:
Allison Naaktgeboren 2014-11-21 16:00:50 -08:00
parent aadc168092
commit 73a4389f88
9 changed files with 76 additions and 40 deletions

View File

@ -8316,9 +8316,6 @@ Parser<ParseHandler>::accumulateTelemetry()
JSContext* cx = context->maybeJSContext();
if (!cx)
return;
JSAccumulateTelemetryDataCallback cb = cx->runtime()->telemetryCallback;
if (!cb)
return;
const char* filename = getFilename();
if (!filename)
return;
@ -8342,13 +8339,13 @@ Parser<ParseHandler>::accumulateTelemetry()
// Call back into Firefox's Telemetry reporter.
if (sawDeprecatedForEach)
(*cb)(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedForEach);
cx->runtime()->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedForEach);
if (sawDeprecatedDestructuringForIn)
(*cb)(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedDestructuringForIn);
cx->runtime()->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedDestructuringForIn);
if (sawDeprecatedLegacyGenerator)
(*cb)(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedLegacyGenerator);
cx->runtime()->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedLegacyGenerator);
if (sawDeprecatedExpressionClosure)
(*cb)(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedExpressionClosure);
cx->runtime()->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, DeprecatedExpressionClosure);
}
template class Parser<FullParseHandler>;

View File

@ -742,28 +742,26 @@ Statistics::endGC()
for (int i = 0; i < PHASE_LIMIT; i++)
phaseTotals[i] += phaseTimes[i];
if (JSAccumulateTelemetryDataCallback cb = runtime->telemetryCallback) {
int64_t total, longest;
gcDuration(&total, &longest);
int64_t total, longest;
gcDuration(&total, &longest);
int64_t sccTotal, sccLongest;
sccDurations(&sccTotal, &sccLongest);
int64_t sccTotal, sccLongest;
sccDurations(&sccTotal, &sccLongest);
(*cb)(JS_TELEMETRY_GC_IS_COMPARTMENTAL, !zoneStats.isCollectingAllZones());
(*cb)(JS_TELEMETRY_GC_MS, t(total));
(*cb)(JS_TELEMETRY_GC_MAX_PAUSE_MS, t(longest));
(*cb)(JS_TELEMETRY_GC_MARK_MS, t(phaseTimes[PHASE_MARK]));
(*cb)(JS_TELEMETRY_GC_SWEEP_MS, t(phaseTimes[PHASE_SWEEP]));
(*cb)(JS_TELEMETRY_GC_MARK_ROOTS_MS, t(phaseTimes[PHASE_MARK_ROOTS]));
(*cb)(JS_TELEMETRY_GC_MARK_GRAY_MS, t(phaseTimes[PHASE_SWEEP_MARK_GRAY]));
(*cb)(JS_TELEMETRY_GC_NON_INCREMENTAL, !!nonincrementalReason);
(*cb)(JS_TELEMETRY_GC_INCREMENTAL_DISABLED, !runtime->gc.isIncrementalGCAllowed());
(*cb)(JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS, t(sccTotal));
(*cb)(JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS, t(sccLongest));
runtime->addTelemetry(JS_TELEMETRY_GC_IS_COMPARTMENTAL, !zoneStats.isCollectingAllZones());
runtime->addTelemetry(JS_TELEMETRY_GC_MS, t(total));
runtime->addTelemetry(JS_TELEMETRY_GC_MAX_PAUSE_MS, t(longest));
runtime->addTelemetry(JS_TELEMETRY_GC_MARK_MS, t(phaseTimes[PHASE_MARK]));
runtime->addTelemetry(JS_TELEMETRY_GC_SWEEP_MS, t(phaseTimes[PHASE_SWEEP]));
runtime->addTelemetry(JS_TELEMETRY_GC_MARK_ROOTS_MS, t(phaseTimes[PHASE_MARK_ROOTS]));
runtime->addTelemetry(JS_TELEMETRY_GC_MARK_GRAY_MS, t(phaseTimes[PHASE_SWEEP_MARK_GRAY]));
runtime->addTelemetry(JS_TELEMETRY_GC_NON_INCREMENTAL, !!nonincrementalReason);
runtime->addTelemetry(JS_TELEMETRY_GC_INCREMENTAL_DISABLED, !runtime->gc.isIncrementalGCAllowed());
runtime->addTelemetry(JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS, t(sccTotal));
runtime->addTelemetry(JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS, t(sccLongest));
double mmu50 = computeMMU(50 * PRMJ_USEC_PER_MSEC);
(*cb)(JS_TELEMETRY_GC_MMU_50, mmu50 * 100);
}
double mmu50 = computeMMU(50 * PRMJ_USEC_PER_MSEC);
runtime->addTelemetry(JS_TELEMETRY_GC_MMU_50, mmu50 * 100);
if (fp)
printStats();
@ -783,8 +781,7 @@ Statistics::beginSlice(const ZoneGCStats &zoneStats, JSGCInvocationKind gckind,
if (!slices.append(data))
CrashAtUnhandlableOOM("Failed to allocate statistics slice.");
if (JSAccumulateTelemetryDataCallback cb = runtime->telemetryCallback)
(*cb)(JS_TELEMETRY_GC_REASON, reason);
runtime->addTelemetry(JS_TELEMETRY_GC_REASON, reason);
// Slice callbacks should only fire for the outermost level
if (++gcDepth == 1) {
@ -801,10 +798,8 @@ Statistics::endSlice()
slices.back().end = PRMJ_Now();
slices.back().endFaults = GetPageFaultCount();
if (JSAccumulateTelemetryDataCallback cb = runtime->telemetryCallback) {
(*cb)(JS_TELEMETRY_GC_SLICE_MS, t(slices.back().end - slices.back().start));
(*cb)(JS_TELEMETRY_GC_RESET, !!slices.back().resetReason);
}
runtime->addTelemetry(JS_TELEMETRY_GC_SLICE_MS, t(slices.back().end - slices.back().start));
runtime->addTelemetry(JS_TELEMETRY_GC_RESET, !!slices.back().resetReason);
bool last = runtime->gc.state() == gc::NO_INCREMENTAL;
if (last)

View File

@ -713,8 +713,23 @@ ErrorReport::init(JSContext *cx, HandleValue exn)
if (exn.isObject()) {
exnObject = &exn.toObject();
reportp = js_ErrorFromException(cx, exnObject);
}
JSCompartment *comp = exnObject->compartment();
JSAddonId *addonId = comp->addonId;
if (addonId) {
UniqueChars addonIdChars(JS_EncodeString(cx, addonId));
const char *filename = strrchr(reportp->filename, '/');
if (filename)
filename++;
else
filename = "COULD_NOT_FIND_FILENAME";
char histogramKey[64];
JS_snprintf(histogramKey, sizeof(histogramKey), "%s %s %u", addonIdChars, filename, reportp->lineno);
cx->runtime()->addTelemetry(JS_TELEMETRY_ADDON_EXCEPTIONS, 1, histogramKey);
}
}
// Be careful not to invoke ToString if we've already successfully extracted
// an error report, since the exception might be wrapped in a security
// wrapper, and ToString-ing it might throw.

View File

@ -681,7 +681,7 @@ js::StringToLinearStringSlow(JSContext *cx, JSString *str)
JS_FRIEND_API(void)
JS_SetAccumulateTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback)
{
rt->telemetryCallback = callback;
rt->setTelemetryCallback(rt, callback);
}
JS_FRIEND_API(JSObject *)

View File

@ -110,11 +110,12 @@ enum {
JS_TELEMETRY_GC_NON_INCREMENTAL,
JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS,
JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS,
JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT
JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT,
JS_TELEMETRY_ADDON_EXCEPTIONS
};
typedef void
(* JSAccumulateTelemetryDataCallback)(int id, uint32_t sample);
(*JSAccumulateTelemetryDataCallback)(int id, uint32_t sample, const char *key);
extern JS_FRIEND_API(void)
JS_SetAccumulateTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback);

View File

@ -458,6 +458,19 @@ JSRuntime::~JSRuntime()
#endif
}
void
JSRuntime::addTelemetry(int id, uint32_t sample, const char *key)
{
if (telemetryCallback)
(*telemetryCallback)(id, sample, key);
}
void
JSRuntime::setTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback)
{
rt->telemetryCallback = callback;
}
void
NewObjectCache::clearNurseryObjects(JSRuntime *rt)
{

View File

@ -702,7 +702,16 @@ struct JSRuntime : public JS::shadow::Runtime,
private:
mozilla::Atomic<uint32_t, mozilla::Relaxed> interrupt_;
mozilla::Atomic<uint32_t, mozilla::Relaxed> interruptPar_;
/* Call this to accumulate telemetry data. */
JSAccumulateTelemetryDataCallback telemetryCallback;
public:
// Accumulates data for Firefox telemetry. |id| is the ID of a JS_TELEMETRY_*
// histogram. |key| provides an additional key to identify the histogram.
// |sample| is the data to add to the histogram.
void addTelemetry(int id, uint32_t sample, const char *key = nullptr);
void setTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback);
enum InterruptMode {
RequestInterruptUrgent,
@ -1085,9 +1094,6 @@ struct JSRuntime : public JS::shadow::Runtime,
/* Structured data callbacks are runtime-wide. */
const JSStructuredCloneCallbacks *structuredCloneCallbacks;
/* Call this to accumulate telemetry data. */
JSAccumulateTelemetryDataCallback telemetryCallback;
/* Optional error reporter. */
JSErrorReporter errorReporter;

View File

@ -2963,7 +2963,7 @@ DiagnosticMemoryCallback(void *ptr, size_t size)
#endif
static void
AccumulateTelemetryCallback(int id, uint32_t sample)
AccumulateTelemetryCallback(int id, uint32_t sample, const char *key)
{
switch (id) {
case JS_TELEMETRY_GC_REASON:
@ -3015,6 +3015,9 @@ AccumulateTelemetryCallback(int id, uint32_t sample)
MOZ_ASSERT(sample <= 3);
Telemetry::Accumulate(Telemetry::JS_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, sample);
break;
case JS_TELEMETRY_ADDON_EXCEPTIONS:
Telemetry::Accumulate(Telemetry::JS_TELEMETRY_ADDON_EXCEPTIONS, nsDependentCString(key), sample);
break;
default:
MOZ_ASSERT_UNREACHABLE("Unexpected JS_TELEMETRY id");
}

View File

@ -324,6 +324,12 @@
"n_values": 10,
"description": "Use of SpiderMonkey's deprecated language extensions in web content: ForEach, DestructuringForIn, LegacyGenerator, ExpressionClosure"
},
"JS_TELEMETRY_ADDON_EXCEPTIONS" : {
"expires_in_version" : "never",
"kind": "count",
"keyed" : true,
"description" : "Exceptions thrown by add-ons"
},
"TELEMETRY_PING": {
"expires_in_version": "default",
"kind": "exponential",