Remove telemetry leftovers from JS engine.

pull/1/head
adeshkp 4 years ago committed by Roy Tam
parent 120aa8a81e
commit 521c918660
  1. 8
      js/public/GCAPI.h
  2. 13
      js/src/frontend/Parser.cpp
  3. 2
      js/src/frontend/Parser.h
  4. 8
      js/src/gc/Nursery.cpp
  5. 219
      js/src/gc/Statistics.cpp
  6. 37
      js/src/jscompartment.cpp
  7. 31
      js/src/jscompartment.h
  8. 65
      js/src/jsexn.cpp
  9. 40
      js/src/jsfriendapi.h
  10. 1
      js/src/tests/user.js
  11. 14
      js/src/vm/Runtime.cpp
  12. 10
      js/src/vm/Runtime.h
  13. 18
      js/src/vm/SelfHosting.cpp
  14. 16
      js/src/vm/Stopwatch.cpp
  15. 30
      js/src/vm/Stopwatch.h
  16. 9
      js/src/wasm/WasmBinaryConstants.h
  17. 3
      js/src/wasm/WasmModule.cpp
  18. 5
      toolkit/components/telemetry/TelemetryHistogram.cpp

@ -119,14 +119,6 @@ enum Reason {
#undef MAKE_REASON
NO_REASON,
NUM_REASONS,
/*
* For telemetry, we want to keep a fixed max bucket size over time so we
* don't have to switch histograms. 100 is conservative; as of this writing
* there are 52. But the cost of extra buckets seems to be low while the
* cost of switching histograms is high.
*/
NUM_TELEMETRY_REASONS = 100
};
/**

@ -3463,7 +3463,6 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling,
if (kind != Arrow) {
#if JS_HAS_EXPR_CLOSURES
addTelemetry(JSCompartment::DeprecatedExpressionClosure);
if (!warnOnceAboutExprClosure())
return false;
#else
@ -5545,7 +5544,6 @@ Parser<ParseHandler>::forStatement(YieldHandling yieldHandling)
if (matched) {
iflags = JSITER_FOREACH;
isForEach = true;
addTelemetry(JSCompartment::DeprecatedForEach);
if (!warnOnceAboutForEach())
return null();
}
@ -6077,7 +6075,6 @@ Parser<ParseHandler>::yieldExpression(InHandling inHandling)
}
pc->functionBox()->setGeneratorKind(LegacyGenerator);
addTelemetry(JSCompartment::DeprecatedLegacyGenerator);
MOZ_FALLTHROUGH;
@ -9588,16 +9585,6 @@ Parser<ParseHandler>::exprInParens(InHandling inHandling, YieldHandling yieldHan
return expr(inHandling, yieldHandling, tripledotHandling, possibleError, PredictInvoked);
}
template <typename ParseHandler>
void
Parser<ParseHandler>::addTelemetry(JSCompartment::DeprecatedLanguageExtension e)
{
JSContext* cx = context->maybeJSContext();
if (!cx)
return;
cx->compartment()->addTelemetry(getFilename(), e);
}
template <typename ParseHandler>
bool
Parser<ParseHandler>::warnOnceAboutExprClosure()

@ -1420,8 +1420,6 @@ class Parser final : private JS::AutoGCRooter, public StrictModeGetter
bool asmJS(Node list);
void addTelemetry(JSCompartment::DeprecatedLanguageExtension e);
bool warnOnceAboutExprClosure();
bool warnOnceAboutForEach();
};

@ -530,7 +530,6 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason)
// the nursery is full, look for object groups that are getting promoted
// excessively and try to pretenure them.
maybeStartProfile(ProfileKey::Pretenure);
uint32_t pretenureCount = 0;
if (promotionRate > 0.8 || reason == JS::gcreason::FULL_STORE_BUFFER) {
JSContext* cx = rt->contextFromMainThread();
for (auto& entry : tenureCounts.entries) {
@ -539,7 +538,6 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason)
if (group->canPreTenure()) {
AutoCompartment ac(cx, group->compartment());
group->setShouldPreTenure(cx);
pretenureCount++;
}
}
}
@ -556,12 +554,6 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason)
minorGcCount_++;
int64_t totalTime = profileTimes_[ProfileKey::Total];
rt->addTelemetry(JS_TELEMETRY_GC_MINOR_US, totalTime);
rt->addTelemetry(JS_TELEMETRY_GC_MINOR_REASON, reason);
if (totalTime > 1000)
rt->addTelemetry(JS_TELEMETRY_GC_MINOR_REASON_LONG, reason);
rt->addTelemetry(JS_TELEMETRY_GC_NURSERY_BYTES, sizeOfHeapCommitted());
rt->addTelemetry(JS_TELEMETRY_GC_PRETENURE_COUNT, pretenureCount);
rt->gc.stats.endNurseryCollection(reason);
TraceMinorGCEnd();

@ -34,13 +34,6 @@ using mozilla::MakeRange;
using mozilla::PodArrayZero;
using mozilla::PodZero;
/*
* If this fails, then you can either delete this assertion and allow all
* larger-numbered reasons to pile up in the last telemetry bucket, or switch
* to GC_REASON_3 and bump the max value.
*/
JS_STATIC_ASSERT(JS::gcreason::NUM_TELEMETRY_REASONS >= JS::gcreason::NUM_REASONS);
const char*
js::gcstats::ExplainInvocationKind(JSGCInvocationKind gckind)
{
@ -92,7 +85,6 @@ struct PhaseInfo
Phase index;
const char* name;
Phase parent;
const uint8_t telemetryBucket;
};
// The zeroth entry in the timing arrays is used for phases that have a
@ -134,78 +126,74 @@ struct DagChildEdge {
*/
static const PhaseInfo phases[] = {
{ PHASE_MUTATOR, "Mutator Running", PHASE_NO_PARENT, 0 },
{ PHASE_GC_BEGIN, "Begin Callback", PHASE_NO_PARENT, 1 },
{ PHASE_WAIT_BACKGROUND_THREAD, "Wait Background Thread", PHASE_NO_PARENT, 2 },
{ PHASE_MARK_DISCARD_CODE, "Mark Discard Code", PHASE_NO_PARENT, 3 },
{ PHASE_RELAZIFY_FUNCTIONS, "Relazify Functions", PHASE_NO_PARENT, 4 },
{ PHASE_PURGE, "Purge", PHASE_NO_PARENT, 5 },
{ PHASE_MARK, "Mark", PHASE_NO_PARENT, 6 },
{ PHASE_UNMARK, "Unmark", PHASE_MARK, 7 },
{ PHASE_MUTATOR, "Mutator Running", PHASE_NO_PARENT },
{ PHASE_GC_BEGIN, "Begin Callback", PHASE_NO_PARENT },
{ PHASE_WAIT_BACKGROUND_THREAD, "Wait Background Thread", PHASE_NO_PARENT },
{ PHASE_MARK_DISCARD_CODE, "Mark Discard Code", PHASE_NO_PARENT },
{ PHASE_RELAZIFY_FUNCTIONS, "Relazify Functions", PHASE_NO_PARENT },
{ PHASE_PURGE, "Purge", PHASE_NO_PARENT },
{ PHASE_MARK, "Mark", PHASE_NO_PARENT },
{ PHASE_UNMARK, "Unmark", PHASE_MARK },
/* PHASE_MARK_ROOTS */
{ PHASE_MARK_DELAYED, "Mark Delayed", PHASE_MARK, 8 },
{ PHASE_SWEEP, "Sweep", PHASE_NO_PARENT, 9 },
{ PHASE_SWEEP_MARK, "Mark During Sweeping", PHASE_SWEEP, 10 },
{ PHASE_SWEEP_MARK_TYPES, "Mark Types During Sweeping", PHASE_SWEEP_MARK, 11 },
{ PHASE_SWEEP_MARK_INCOMING_BLACK, "Mark Incoming Black Pointers", PHASE_SWEEP_MARK, 12 },
{ PHASE_SWEEP_MARK_WEAK, "Mark Weak", PHASE_SWEEP_MARK, 13 },
{ PHASE_SWEEP_MARK_INCOMING_GRAY, "Mark Incoming Gray Pointers", PHASE_SWEEP_MARK, 14 },
{ PHASE_SWEEP_MARK_GRAY, "Mark Gray", PHASE_SWEEP_MARK, 15 },
{ PHASE_SWEEP_MARK_GRAY_WEAK, "Mark Gray and Weak", PHASE_SWEEP_MARK, 16 },
{ PHASE_FINALIZE_START, "Finalize Start Callbacks", PHASE_SWEEP, 17 },
{ PHASE_WEAK_ZONEGROUP_CALLBACK, "Per-Slice Weak Callback", PHASE_FINALIZE_START, 57 },
{ PHASE_WEAK_COMPARTMENT_CALLBACK, "Per-Compartment Weak Callback", PHASE_FINALIZE_START, 58 },
{ PHASE_SWEEP_ATOMS, "Sweep Atoms", PHASE_SWEEP, 18 },
{ PHASE_SWEEP_SYMBOL_REGISTRY, "Sweep Symbol Registry", PHASE_SWEEP, 19 },
{ PHASE_SWEEP_COMPARTMENTS, "Sweep Compartments", PHASE_SWEEP, 20 },
{ PHASE_SWEEP_DISCARD_CODE, "Sweep Discard Code", PHASE_SWEEP_COMPARTMENTS, 21 },
{ PHASE_SWEEP_INNER_VIEWS, "Sweep Inner Views", PHASE_SWEEP_COMPARTMENTS, 22 },
{ PHASE_SWEEP_CC_WRAPPER, "Sweep Cross Compartment Wrappers", PHASE_SWEEP_COMPARTMENTS, 23 },
{ PHASE_SWEEP_BASE_SHAPE, "Sweep Base Shapes", PHASE_SWEEP_COMPARTMENTS, 24 },
{ PHASE_SWEEP_INITIAL_SHAPE, "Sweep Initial Shapes", PHASE_SWEEP_COMPARTMENTS, 25 },
{ PHASE_SWEEP_TYPE_OBJECT, "Sweep Type Objects", PHASE_SWEEP_COMPARTMENTS, 26 },
{ PHASE_SWEEP_BREAKPOINT, "Sweep Breakpoints", PHASE_SWEEP_COMPARTMENTS, 27 },
{ PHASE_SWEEP_REGEXP, "Sweep Regexps", PHASE_SWEEP_COMPARTMENTS, 28 },
{ PHASE_SWEEP_MISC, "Sweep Miscellaneous", PHASE_SWEEP_COMPARTMENTS, 29 },
{ PHASE_SWEEP_TYPES, "Sweep type information", PHASE_SWEEP_COMPARTMENTS, 30 },
{ PHASE_SWEEP_TYPES_BEGIN, "Sweep type tables and compilations", PHASE_SWEEP_TYPES, 31 },
{ PHASE_SWEEP_TYPES_END, "Free type arena", PHASE_SWEEP_TYPES, 32 },
{ PHASE_SWEEP_OBJECT, "Sweep Object", PHASE_SWEEP, 33 },
{ PHASE_SWEEP_STRING, "Sweep String", PHASE_SWEEP, 34 },
{ PHASE_SWEEP_SCRIPT, "Sweep Script", PHASE_SWEEP, 35 },
{ PHASE_SWEEP_SCOPE, "Sweep Scope", PHASE_SWEEP, 59 },
{ PHASE_SWEEP_SHAPE, "Sweep Shape", PHASE_SWEEP, 36 },
{ PHASE_SWEEP_JITCODE, "Sweep JIT code", PHASE_SWEEP, 37 },
{ PHASE_FINALIZE_END, "Finalize End Callback", PHASE_SWEEP, 38 },
{ PHASE_DESTROY, "Deallocate", PHASE_SWEEP, 39 },
{ PHASE_COMPACT, "Compact", PHASE_NO_PARENT, 40 },
{ PHASE_COMPACT_MOVE, "Compact Move", PHASE_COMPACT, 41 },
{ PHASE_COMPACT_UPDATE, "Compact Update", PHASE_COMPACT, 42 },
{ PHASE_MARK_DELAYED, "Mark Delayed", PHASE_MARK },
{ PHASE_SWEEP, "Sweep", PHASE_NO_PARENT },
{ PHASE_SWEEP_MARK, "Mark During Sweeping", PHASE_SWEEP },
{ PHASE_SWEEP_MARK_TYPES, "Mark Types During Sweeping", PHASE_SWEEP_MARK },
{ PHASE_SWEEP_MARK_INCOMING_BLACK, "Mark Incoming Black Pointers", PHASE_SWEEP_MARK },
{ PHASE_SWEEP_MARK_WEAK, "Mark Weak", PHASE_SWEEP_MARK },
{ PHASE_SWEEP_MARK_INCOMING_GRAY, "Mark Incoming Gray Pointers", PHASE_SWEEP_MARK },
{ PHASE_SWEEP_MARK_GRAY, "Mark Gray", PHASE_SWEEP_MARK },
{ PHASE_SWEEP_MARK_GRAY_WEAK, "Mark Gray and Weak", PHASE_SWEEP_MARK },
{ PHASE_FINALIZE_START, "Finalize Start Callbacks", PHASE_SWEEP },
{ PHASE_WEAK_ZONEGROUP_CALLBACK, "Per-Slice Weak Callback", PHASE_FINALIZE_START },
{ PHASE_WEAK_COMPARTMENT_CALLBACK, "Per-Compartment Weak Callback", PHASE_FINALIZE_START },
{ PHASE_SWEEP_ATOMS, "Sweep Atoms", PHASE_SWEEP },
{ PHASE_SWEEP_SYMBOL_REGISTRY, "Sweep Symbol Registry", PHASE_SWEEP },
{ PHASE_SWEEP_COMPARTMENTS, "Sweep Compartments", PHASE_SWEEP },
{ PHASE_SWEEP_DISCARD_CODE, "Sweep Discard Code", PHASE_SWEEP_COMPARTMENTS },
{ PHASE_SWEEP_INNER_VIEWS, "Sweep Inner Views", PHASE_SWEEP_COMPARTMENTS },
{ PHASE_SWEEP_CC_WRAPPER, "Sweep Cross Compartment Wrappers", PHASE_SWEEP_COMPARTMENTS },
{ PHASE_SWEEP_BASE_SHAPE, "Sweep Base Shapes", PHASE_SWEEP_COMPARTMENTS },
{ PHASE_SWEEP_INITIAL_SHAPE, "Sweep Initial Shapes", PHASE_SWEEP_COMPARTMENTS },
{ PHASE_SWEEP_TYPE_OBJECT, "Sweep Type Objects", PHASE_SWEEP_COMPARTMENTS },
{ PHASE_SWEEP_BREAKPOINT, "Sweep Breakpoints", PHASE_SWEEP_COMPARTMENTS },
{ PHASE_SWEEP_REGEXP, "Sweep Regexps", PHASE_SWEEP_COMPARTMENTS },
{ PHASE_SWEEP_MISC, "Sweep Miscellaneous", PHASE_SWEEP_COMPARTMENTS },
{ PHASE_SWEEP_TYPES, "Sweep type information", PHASE_SWEEP_COMPARTMENTS },
{ PHASE_SWEEP_TYPES_BEGIN, "Sweep type tables and compilations", PHASE_SWEEP_TYPES },
{ PHASE_SWEEP_TYPES_END, "Free type arena", PHASE_SWEEP_TYPES },
{ PHASE_SWEEP_OBJECT, "Sweep Object", PHASE_SWEEP },
{ PHASE_SWEEP_STRING, "Sweep String", PHASE_SWEEP },
{ PHASE_SWEEP_SCRIPT, "Sweep Script", PHASE_SWEEP },
{ PHASE_SWEEP_SCOPE, "Sweep Scope", PHASE_SWEEP },
{ PHASE_SWEEP_SHAPE, "Sweep Shape", PHASE_SWEEP },
{ PHASE_SWEEP_JITCODE, "Sweep JIT code", PHASE_SWEEP },
{ PHASE_FINALIZE_END, "Finalize End Callback", PHASE_SWEEP },
{ PHASE_DESTROY, "Deallocate", PHASE_SWEEP },
{ PHASE_COMPACT, "Compact", PHASE_NO_PARENT },
{ PHASE_COMPACT_MOVE, "Compact Move", PHASE_COMPACT },
{ PHASE_COMPACT_UPDATE, "Compact Update", PHASE_COMPACT },
/* PHASE_MARK_ROOTS */
{ PHASE_COMPACT_UPDATE_CELLS, "Compact Update Cells", PHASE_COMPACT_UPDATE, 43 },
{ PHASE_GC_END, "End Callback", PHASE_NO_PARENT, 44 },
{ PHASE_MINOR_GC, "All Minor GCs", PHASE_NO_PARENT, 45 },
{ PHASE_COMPACT_UPDATE_CELLS, "Compact Update Cells", PHASE_COMPACT_UPDATE },
{ PHASE_GC_END, "End Callback", PHASE_NO_PARENT },
{ PHASE_MINOR_GC, "All Minor GCs", PHASE_NO_PARENT },
/* PHASE_MARK_ROOTS */
{ PHASE_EVICT_NURSERY, "Minor GCs to Evict Nursery", PHASE_NO_PARENT, 46 },
{ PHASE_EVICT_NURSERY, "Minor GCs to Evict Nursery", PHASE_NO_PARENT },
/* PHASE_MARK_ROOTS */
{ PHASE_TRACE_HEAP, "Trace Heap", PHASE_NO_PARENT, 47 },
{ PHASE_TRACE_HEAP, "Trace Heap", PHASE_NO_PARENT },
/* PHASE_MARK_ROOTS */
{ PHASE_BARRIER, "Barriers", PHASE_NO_PARENT, 55 },
{ PHASE_UNMARK_GRAY, "Unmark gray", PHASE_BARRIER, 56 },
{ PHASE_MARK_ROOTS, "Mark Roots", PHASE_MULTI_PARENTS, 48 },
{ PHASE_BUFFER_GRAY_ROOTS, "Buffer Gray Roots", PHASE_MARK_ROOTS, 49 },
{ PHASE_MARK_CCWS, "Mark Cross Compartment Wrappers", PHASE_MARK_ROOTS, 50 },
{ PHASE_MARK_STACK, "Mark C and JS stacks", PHASE_MARK_ROOTS, 51 },
{ PHASE_MARK_RUNTIME_DATA, "Mark Runtime-wide Data", PHASE_MARK_ROOTS, 52 },
{ PHASE_MARK_EMBEDDING, "Mark Embedding", PHASE_MARK_ROOTS, 53 },
{ PHASE_MARK_COMPARTMENTS, "Mark Compartments", PHASE_MARK_ROOTS, 54 },
{ PHASE_PURGE_SHAPE_TABLES, "Purge ShapeTables", PHASE_NO_PARENT, 60 },
{ PHASE_LIMIT, nullptr, PHASE_NO_PARENT, 60 }
// Current number of telemetryBuckets is 60. If you insert new phases
// somewhere, start at that number and count up. Do not change any existing
// numbers.
{ PHASE_BARRIER, "Barriers", PHASE_NO_PARENT },
{ PHASE_UNMARK_GRAY, "Unmark gray", PHASE_BARRIER },
{ PHASE_MARK_ROOTS, "Mark Roots", PHASE_MULTI_PARENTS },
{ PHASE_BUFFER_GRAY_ROOTS, "Buffer Gray Roots", PHASE_MARK_ROOTS },
{ PHASE_MARK_CCWS, "Mark Cross Compartment Wrappers", PHASE_MARK_ROOTS },
{ PHASE_MARK_STACK, "Mark C and JS stacks", PHASE_MARK_ROOTS },
{ PHASE_MARK_RUNTIME_DATA, "Mark Runtime-wide Data", PHASE_MARK_ROOTS },
{ PHASE_MARK_EMBEDDING, "Mark Embedding", PHASE_MARK_ROOTS },
{ PHASE_MARK_COMPARTMENTS, "Mark Compartments", PHASE_MARK_ROOTS },
{ PHASE_PURGE_SHAPE_TABLES, "Purge ShapeTables", PHASE_NO_PARENT },
{ PHASE_LIMIT, nullptr, PHASE_NO_PARENT }
};
static ExtraPhaseInfo phaseExtra[PHASE_LIMIT] = { { 0, 0 } };
@ -845,12 +833,6 @@ Statistics::~Statistics()
/* static */ bool
Statistics::initialize()
{
for (size_t i = 0; i < PHASE_LIMIT; i++) {
MOZ_ASSERT(phases[i].index == i);
for (size_t j = 0; j < PHASE_LIMIT; j++)
MOZ_ASSERT_IF(i != j, phases[i].telemetryBucket != phases[j].telemetryBucket);
}
// Create a static table of descendants for every phase with multiple
// children. This assumes that all descendants come linearly in the
// list, which is reasonable since full dags are not supported; any
@ -925,32 +907,6 @@ Statistics::getMaxGCPauseSinceClear()
return maxPauseInInterval;
}
// Sum up the time for a phase, including instances of the phase with different
// parents.
static int64_t
SumPhase(Phase phase, const Statistics::PhaseTimeTable times)
{
int64_t sum = 0;
for (auto i : MakeRange(Statistics::NumTimingArrays))
sum += times[i][phase];
return sum;
}
static Phase
LongestPhase(const Statistics::PhaseTimeTable times)
{
int64_t longestTime = 0;
Phase longestPhase = PHASE_NONE;
for (size_t i = 0; i < PHASE_LIMIT; ++i) {
int64_t phaseTime = SumPhase(Phase(i), times);
if (phaseTime > longestTime) {
longestTime = phaseTime;
longestPhase = Phase(i);
}
}
return longestPhase;
}
void
Statistics::printStats()
{
@ -985,34 +941,6 @@ Statistics::endGC()
int64_t total, longest;
gcDuration(&total, &longest);
int64_t sccTotal, sccLongest;
sccDurations(&sccTotal, &sccLongest);
runtime->addTelemetry(JS_TELEMETRY_GC_IS_ZONE_GC, !zoneStats.isCollectingAllZones());
runtime->addTelemetry(JS_TELEMETRY_GC_MS, t(total));
runtime->addTelemetry(JS_TELEMETRY_GC_MAX_PAUSE_MS, t(longest));
int64_t markTotal = SumPhase(PHASE_MARK, phaseTimes);
int64_t markRootsTotal = SumPhase(PHASE_MARK_ROOTS, phaseTimes);
runtime->addTelemetry(JS_TELEMETRY_GC_MARK_MS, t(markTotal));
runtime->addTelemetry(JS_TELEMETRY_GC_SWEEP_MS, t(phaseTimes[PHASE_DAG_NONE][PHASE_SWEEP]));
if (runtime->gc.isCompactingGc()) {
runtime->addTelemetry(JS_TELEMETRY_GC_COMPACT_MS,
t(phaseTimes[PHASE_DAG_NONE][PHASE_COMPACT]));
}
runtime->addTelemetry(JS_TELEMETRY_GC_MARK_ROOTS_MS, t(markRootsTotal));
runtime->addTelemetry(JS_TELEMETRY_GC_MARK_GRAY_MS, t(phaseTimes[PHASE_DAG_NONE][PHASE_SWEEP_MARK_GRAY]));
runtime->addTelemetry(JS_TELEMETRY_GC_NON_INCREMENTAL, nonincremental());
if (nonincremental())
runtime->addTelemetry(JS_TELEMETRY_GC_NON_INCREMENTAL_REASON, uint32_t(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));
if (!aborted) {
double mmu50 = computeMMU(50 * PRMJ_USEC_PER_MSEC);
runtime->addTelemetry(JS_TELEMETRY_GC_MMU_50, mmu50 * 100);
}
if (fp)
printStats();
@ -1061,8 +989,6 @@ Statistics::beginSlice(const ZoneGCStats& zoneStats, JSGCInvocationKind gckind,
return;
}
runtime->addTelemetry(JS_TELEMETRY_GC_REASON, reason);
// Slice callbacks should only fire for the outermost level.
if (gcDepth == 1) {
bool wasFullGC = zoneStats.isCollectingAllZones();
@ -1082,25 +1008,6 @@ Statistics::endSlice()
slices.back().endFaults = GetPageFaultCount();
slices.back().finalState = runtime->gc.state();
int64_t sliceTime = slices.back().end - slices.back().start;
runtime->addTelemetry(JS_TELEMETRY_GC_SLICE_MS, t(sliceTime));
runtime->addTelemetry(JS_TELEMETRY_GC_RESET, slices.back().wasReset());
if (slices.back().wasReset())
runtime->addTelemetry(JS_TELEMETRY_GC_RESET_REASON, uint32_t(slices.back().resetReason));
if (slices.back().budget.isTimeBudget()) {
int64_t budget_ms = slices.back().budget.timeBudget.budget;
runtime->addTelemetry(JS_TELEMETRY_GC_BUDGET_MS, budget_ms);
if (budget_ms == runtime->gc.defaultSliceBudget())
runtime->addTelemetry(JS_TELEMETRY_GC_ANIMATION_MS, t(sliceTime));
// Record any phase that goes more than 2x over its budget.
if (sliceTime > 2 * budget_ms * 1000) {
Phase longest = LongestPhase(slices.back().phaseTimes);
runtime->addTelemetry(JS_TELEMETRY_GC_SLOW_PHASE, phases[longest].telemetryBucket);
}
}
sliceCount_++;
}

@ -41,7 +41,6 @@ using namespace js::gc;
using namespace js::jit;
using mozilla::DebugOnly;
using mozilla::PodArrayZero;
JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options = JS::CompartmentOptions())
: creationOptions_(options.creationOptions()),
@ -91,7 +90,6 @@ JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options =
unmappedArgumentsTemplate_(nullptr),
lcovOutput()
{
PodArrayZero(sawDeprecatedLanguageExtension);
runtime_->numCompartments++;
MOZ_ASSERT_IF(creationOptions_.mergeable(),
creationOptions_.invisibleToDebugger());
@ -99,8 +97,6 @@ JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options =
JSCompartment::~JSCompartment()
{
reportTelemetry();
// Write the code coverage information in a file.
JSRuntime* rt = runtimeFromMainThread();
if (rt->lcovOutput.isEnabled())
@ -1268,39 +1264,6 @@ JSCompartment::addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
*privateData += callback(mallocSizeOf, this);
}
void
JSCompartment::reportTelemetry()
{
// Only report telemetry for web content and add-ons, not chrome JS.
if (isSystem_)
return;
// Hazard analysis can't tell that the telemetry callbacks don't GC.
JS::AutoSuppressGCAnalysis nogc;
int id = creationOptions_.addonIdOrNull()
? JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_ADDONS
: JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT;
// Call back into Firefox's Telemetry reporter.
for (size_t i = 0; i < DeprecatedLanguageExtensionCount; i++) {
if (sawDeprecatedLanguageExtension[i])
runtime_->addTelemetry(id, i);
}
}
void
JSCompartment::addTelemetry(const char* filename, DeprecatedLanguageExtension e)
{
// Only report telemetry for web content and add-ons, not chrome JS.
if (isSystem_)
return;
if (!creationOptions_.addonIdOrNull() && (!filename || strncmp(filename, "http", 4) != 0))
return;
sawDeprecatedLanguageExtension[e] = true;
}
HashNumber
JSCompartment::randomHashCode()
{

@ -344,13 +344,6 @@ struct JSCompartment
isAtomsCompartment_ = true;
}
// Used to approximate non-content code when reporting telemetry.
inline bool isProbablySystemOrAddonCode() const {
if (creationOptions_.addonIdOrNull())
return true;
return isSystem_;
}
private:
JSPrincipals* principals_;
bool isSystem_;
@ -879,34 +872,10 @@ struct JSCompartment
return jitCompartment_;
}
enum DeprecatedLanguageExtension {
DeprecatedForEach = 0, // JS 1.6+
// NO LONGER USING 1
DeprecatedLegacyGenerator = 2, // JS 1.7+
DeprecatedExpressionClosure = 3, // Added in JS 1.8
// NO LONGER USING 4
// NO LONGER USING 5
// NO LONGER USING 6
// NO LONGER USING 7
// NO LONGER USING 8
// NO LONGER USING 9
DeprecatedBlockScopeFunRedecl = 10,
DeprecatedLanguageExtensionCount
};
js::ArgumentsObject* getOrCreateArgumentsTemplateObject(JSContext* cx, bool mapped);
js::ArgumentsObject* maybeArgumentsTemplateObject(bool mapped) const;
private:
// Used for collecting telemetry on SpiderMonkey's deprecated language extensions.
bool sawDeprecatedLanguageExtension[DeprecatedLanguageExtensionCount];
void reportTelemetry();
public:
void addTelemetry(const char* filename, DeprecatedLanguageExtension e);
public:
// Aggregated output used to collect JSScript hit counts when code coverage
// is enabled.

@ -707,67 +707,6 @@ ErrorReport::~ErrorReport()
{
}
void
ErrorReport::ReportAddonExceptionToTelementry(JSContext* cx)
{
MOZ_ASSERT(exnObject);
RootedObject unwrapped(cx, UncheckedUnwrap(exnObject));
MOZ_ASSERT(unwrapped, "UncheckedUnwrap failed?");
// There is not much we can report if the exception is not an ErrorObject, let's ignore those.
if (!unwrapped->is<ErrorObject>())
return;
Rooted<ErrorObject*> errObj(cx, &unwrapped->as<ErrorObject>());
RootedObject stack(cx, errObj->stack());
// Let's ignore TOP level exceptions. For regular add-ons those will not be reported anyway,
// for SDK based once it should not be a valid case either.
// At this point the frame stack is unwound but the exception object stored the stack so let's
// use that for getting the function name.
if (!stack)
return;
JSCompartment* comp = stack->compartment();
JSAddonId* addonId = comp->creationOptions().addonIdOrNull();
// We only want to send the report if the scope that just have thrown belongs to an add-on.
// Let's check the compartment of the youngest function on the stack, to determine that.
if (!addonId)
return;
RootedString funnameString(cx);
JS::SavedFrameResult result = GetSavedFrameFunctionDisplayName(cx, stack, &funnameString);
// AccessDenied should never be the case here for add-ons but let's not risk it.
JSAutoByteString bytes;
const char* funname = nullptr;
bool denied = result == JS::SavedFrameResult::AccessDenied;
funname = denied ? "unknown"
: funnameString ? AtomToPrintableString(cx,
&funnameString->asAtom(),
&bytes)
: "anonymous";
UniqueChars addonIdChars(JS_EncodeString(cx, addonId));
const char* filename = nullptr;
if (reportp && reportp->filename) {
filename = strrchr(reportp->filename, '/');
if (filename)
filename++;
}
if (!filename) {
filename = "FILE_NOT_FOUND";
}
char histogramKey[64];
SprintfLiteral(histogramKey, "%s %s %s %u",
addonIdChars.get(),
funname,
filename,
(reportp ? reportp->lineno : 0) );
cx->runtime()->addTelemetry(JS_TELEMETRY_ADDON_EXCEPTIONS, 1, histogramKey);
}
bool
ErrorReport::init(JSContext* cx, HandleValue exn,
SniffingBehavior sniffingBehavior)
@ -786,10 +725,6 @@ ErrorReport::init(JSContext* cx, HandleValue exn,
JSMSG_ERR_DURING_THROW);
return false;
}
// Let's see if the exception is from add-on code, if so, it should be reported
// to telementry.
ReportAddonExceptionToTelementry(cx);
}

@ -105,43 +105,6 @@ JS_TraceShapeCycleCollectorChildren(JS::CallbackTracer* trc, JS::GCCellPtr shape
extern JS_FRIEND_API(void)
JS_TraceObjectGroupCycleCollectorChildren(JS::CallbackTracer* trc, JS::GCCellPtr group);
enum {
JS_TELEMETRY_GC_REASON,
JS_TELEMETRY_GC_IS_ZONE_GC,
JS_TELEMETRY_GC_MS,
JS_TELEMETRY_GC_BUDGET_MS,
JS_TELEMETRY_GC_ANIMATION_MS,
JS_TELEMETRY_GC_MAX_PAUSE_MS,
JS_TELEMETRY_GC_MARK_MS,
JS_TELEMETRY_GC_SWEEP_MS,
JS_TELEMETRY_GC_COMPACT_MS,
JS_TELEMETRY_GC_MARK_ROOTS_MS,
JS_TELEMETRY_GC_MARK_GRAY_MS,
JS_TELEMETRY_GC_SLICE_MS,
JS_TELEMETRY_GC_SLOW_PHASE,
JS_TELEMETRY_GC_MMU_50,
JS_TELEMETRY_GC_RESET,
JS_TELEMETRY_GC_RESET_REASON,
JS_TELEMETRY_GC_INCREMENTAL_DISABLED,
JS_TELEMETRY_GC_NON_INCREMENTAL,
JS_TELEMETRY_GC_NON_INCREMENTAL_REASON,
JS_TELEMETRY_GC_SCC_SWEEP_TOTAL_MS,
JS_TELEMETRY_GC_SCC_SWEEP_MAX_PAUSE_MS,
JS_TELEMETRY_GC_MINOR_REASON,
JS_TELEMETRY_GC_MINOR_REASON_LONG,
JS_TELEMETRY_GC_MINOR_US,
JS_TELEMETRY_GC_NURSERY_BYTES,
JS_TELEMETRY_GC_PRETENURE_COUNT,
JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT,
JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_ADDONS,
JS_TELEMETRY_ADDON_EXCEPTIONS,
JS_TELEMETRY_AOT_USAGE,
JS_TELEMETRY_END
};
typedef void
(*JSAccumulateTelemetryDataCallback)(int id, uint32_t sample, const char* key);
extern JS_FRIEND_API(bool)
JS_GetIsSecureContext(JSCompartment* compartment);
@ -1453,9 +1416,6 @@ struct MOZ_STACK_CLASS JS_FRIEND_API(ErrorReport)
bool populateUncaughtExceptionReportUTF8(JSContext* cx, ...);
bool populateUncaughtExceptionReportUTF8VA(JSContext* cx, va_list ap);
// Reports exceptions from add-on scopes to telementry.
void ReportAddonExceptionToTelementry(JSContext* cx);
// We may have a provided JSErrorReport, so need a way to represent that.
JSErrorReport* reportp;

@ -22,7 +22,6 @@ user_pref("javascript.options.strict", false);
user_pref("javascript.options.werror", false);
user_pref("toolkit.startup.max_resumed_crashes", -1);
user_pref("security.turn_off_all_security_so_that_viruses_can_take_over_this_computer", true);
user_pref("toolkit.telemetry.enabled", false);
user_pref("browser.safebrowsing.phishing.enabled", false);
user_pref("browser.safebrowsing.malware.enabled", false);
user_pref("browser.safebrowsing.forbiddenURIs.enabled", false);

@ -147,7 +147,6 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
updateChildRuntimeCount(parentRuntime),
#endif
interrupt_(false),
telemetryCallback(nullptr),
handlingSegFault(false),
handlingJitInterrupt_(false),
interruptCallbackDisabled(false),
@ -451,19 +450,6 @@ JSRuntime::destroyRuntime()
#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
JSRuntime::addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::RuntimeSizes* rtSizes)
{

@ -577,17 +577,7 @@ struct JSRuntime : public JS::shadow::Runtime,
#endif
mozilla::Atomic<uint32_t, mozilla::Relaxed> interrupt_;
/* 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,
RequestInterruptCanWait

@ -1903,23 +1903,6 @@ intrinsic_RuntimeDefaultLocale(JSContext* cx, unsigned argc, Value* vp)
return true;
}
static bool
intrinsic_AddContentTelemetry(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
MOZ_ASSERT(args.length() == 2);
int id = args[0].toInt32();
MOZ_ASSERT(id < JS_TELEMETRY_END);
MOZ_ASSERT(id >= 0);
if (!cx->compartment()->isProbablySystemOrAddonCode())
cx->runtime()->addTelemetry(id, args[1].toInt32());
args.rval().setUndefined();
return true;
}
static bool
intrinsic_ConstructFunction(JSContext* cx, unsigned argc, Value* vp)
{
@ -2273,7 +2256,6 @@ static const JSFunctionSpec intrinsic_functions[] = {
JS_FN("DecompileArg", intrinsic_DecompileArg, 2,0),
JS_FN("_FinishBoundFunctionInit", intrinsic_FinishBoundFunctionInit, 3,0),
JS_FN("RuntimeDefaultLocale", intrinsic_RuntimeDefaultLocale, 0,0),
JS_FN("AddContentTelemetry", intrinsic_AddContentTelemetry, 2,0),
JS_INLINABLE_FN("_IsConstructing", intrinsic_IsConstructing, 0,0,
IntrinsicIsConstructing),

@ -334,11 +334,6 @@ AutoStopwatch::exit()
const uint64_t cyclesEnd = getCycles(runtime);
cyclesDelta = cyclesEnd - cyclesStart_; // Always >= 0 by definition of `getCycles`.
}
#if WINVER >= 0x600
updateTelemetry(cpuStart_, cpuEnd);
#elif defined(__linux__)
updateTelemetry(cpuStart_, cpuEnd);
#endif // WINVER >= 0x600 || _linux__
}
uint64_t CPOWTimeDelta = 0;
@ -350,17 +345,6 @@ AutoStopwatch::exit()
return addToGroups(cyclesDelta, CPOWTimeDelta);
}
void
AutoStopwatch::updateTelemetry(const cpuid_t& cpuStart_, const cpuid_t& cpuEnd)
{
JSRuntime* runtime = cx_->runtime();
if (isSameCPU(cpuStart_, cpuEnd))
runtime->performanceMonitoring.testCpuRescheduling.stayed += 1;
else
runtime->performanceMonitoring.testCpuRescheduling.moved += 1;
}
PerformanceGroup*
AutoStopwatch::acquireGroup(PerformanceGroup* group)
{

@ -217,33 +217,6 @@ struct PerformanceMonitoring {
*/
uint64_t monotonicReadTimestampCounter();
/**
* Data extracted by the AutoStopwatch to determine how often
* we reschedule the process to a different CPU during the
* execution of JS.
*
* Warning: These values are incremented *only* on platforms
* that offer a syscall/libcall to check on which CPU a
* process is currently executed.
*/
struct TestCpuRescheduling
{
// Incremented once we have finished executing code
// in a group, if the CPU on which we started
// execution is the same as the CPU on which
// we finished.
uint64_t stayed;
// Incremented once we have finished executing code
// in a group, if the CPU on which we started
// execution is different from the CPU on which
// we finished.
uint64_t moved;
TestCpuRescheduling()
: stayed(0),
moved(0)
{ }
};
TestCpuRescheduling testCpuRescheduling;
private:
PerformanceMonitoring(const PerformanceMonitoring&) = delete;
PerformanceMonitoring& operator=(const PerformanceMonitoring&) = delete;
@ -375,9 +348,6 @@ class AutoStopwatch final {
// Add recent changes to a single group. Mark the group as changed recently.
bool addToGroup(JSRuntime* runtime, uint64_t cyclesDelta, uint64_t CPOWTimeDelta, PerformanceGroup* group);
// Update telemetry statistics.
void updateTelemetry(const cpuid_t& a, const cpuid_t& b);
// Perform a subtraction for a quantity that should be monotonic
// but is not guaranteed to be so.
//

@ -434,15 +434,6 @@ enum class Op
Limit
};
// Telemetry sample values for the JS_AOT_USAGE key, indicating whether asm.js
// or WebAssembly is used.
enum class Telemetry
{
ASMJS = 0,
WASM = 1
};
} // namespace wasm
} // namespace js

@ -1066,8 +1066,5 @@ Module::instantiate(JSContext* cx,
return false;
}
uint32_t mode = uint32_t(metadata().isAsmJS() ? Telemetry::ASMJS : Telemetry::WASM);
cx->runtime()->addTelemetry(JS_TELEMETRY_AOT_USAGE, mode);
return true;
}

@ -2090,11 +2090,6 @@ void TelemetryHistogram::InitializeGlobalState(bool canRecordBase,
// don't go unnoticed.
// TODO: Compare explicitly with gHistograms[<histogram id>].bucketCount here
// once we can make gHistograms constexpr (requires VS2015).
static_assert((JS::gcreason::NUM_TELEMETRY_REASONS == 100),
"NUM_TELEMETRY_REASONS is assumed to be a fixed value in Histograms.json."
" If this was an intentional change, update this assert with its value "
"and update the n_values for the following in Histograms.json: "
"GC_MINOR_REASON, GC_MINOR_REASON_LONG, GC_REASON_2");
static_assert((mozilla::StartupTimeline::MAX_EVENT_ID == 16),
"MAX_EVENT_ID is assumed to be a fixed value in Histograms.json. If this"
" was an intentional change, update this assert with its value and update"

Loading…
Cancel
Save