Bug 1130123 - Part 1: Move deprecated JS telemetry from Parser to JSCompartment. r=jandem

This commit is contained in:
Chris Peterson 2015-02-10 23:17:43 -08:00
parent 7b4c630373
commit 7cfc231773
5 changed files with 51 additions and 63 deletions

View File

@ -510,12 +510,6 @@ Parser<ParseHandler>::Parser(ExclusiveContext *cx, LifoAlloc *alloc,
#endif
abortedSyntaxParse(false),
isUnexpectedEOF_(false),
sawDeprecatedForEach(false),
sawDeprecatedDestructuringForIn(false),
sawDeprecatedLegacyGenerator(false),
sawDeprecatedExpressionClosure(false),
sawDeprecatedLetBlock(false),
sawDeprecatedLetExpression(false),
handler(cx, *alloc, tokenStream, syntaxParser, lazyOuterFunction)
{
{
@ -551,8 +545,6 @@ Parser<ParseHandler>::~Parser()
{
MOZ_ASSERT(checkOptionsCalled);
accumulateTelemetry();
alloc.release(tempPoolMark);
/*
@ -2544,7 +2536,7 @@ Parser<ParseHandler>::functionArgsAndBodyGeneric(Node pn, HandleFunction fun, Fu
if (kind != Arrow) {
#if JS_HAS_EXPR_CLOSURES
sawDeprecatedExpressionClosure = true;
addTelemetry(JSCompartment::DeprecatedExpressionClosure);
#else
report(ParseError, false, null(), JSMSG_CURLY_BEFORE_BODY);
return false;
@ -3690,7 +3682,7 @@ Parser<ParseHandler>::deprecatedLetBlockOrExpression(LetContext letContext)
return null();
MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_LET);
sawDeprecatedLetBlock = true;
addTelemetry(JSCompartment::DeprecatedLetBlock);
if (!report(ParseWarning, pc->sc->strict, expr, JSMSG_DEPRECATED_LET_BLOCK))
return null();
} else {
@ -3699,7 +3691,7 @@ Parser<ParseHandler>::deprecatedLetBlockOrExpression(LetContext letContext)
if (!expr)
return null();
sawDeprecatedLetExpression = true;
addTelemetry(JSCompartment::DeprecatedLetExpression);
if (!report(ParseWarning, pc->sc->strict, expr, JSMSG_DEPRECATED_LET_EXPRESSION))
return null();
}
@ -4621,7 +4613,7 @@ Parser<FullParseHandler>::forStatement()
if (matched) {
iflags = JSITER_FOREACH;
isForEach = true;
sawDeprecatedForEach = true;
addTelemetry(JSCompartment::DeprecatedForEach);
if (versionNumber() < JSVERSION_LATEST) {
if (!report(ParseWarning, pc->sc->strict, null(), JSMSG_DEPRECATED_FOR_EACH))
return null();
@ -4856,7 +4848,7 @@ Parser<FullParseHandler>::forStatement()
*/
if (!isForEach && headKind == PNK_FORIN) {
iflags |= JSITER_FOREACH | JSITER_KEYVALUE;
sawDeprecatedDestructuringForIn = true;
addTelemetry(JSCompartment::DeprecatedDestructuringForIn);
}
}
break;
@ -5422,7 +5414,7 @@ Parser<ParseHandler>::yieldExpression()
}
pc->sc->asFunctionBox()->setGeneratorKind(LegacyGenerator);
sawDeprecatedLegacyGenerator = true;
addTelemetry(JSCompartment::DeprecatedLegacyGenerator);
if (pc->funHasReturnExpr) {
/* As in Python (see PEP-255), disallow return v; in generators. */
@ -6819,7 +6811,7 @@ Parser<FullParseHandler>::legacyComprehensionTail(ParseNode *bodyExpr, unsigned
return null();
if (matched) {
pn2->pn_iflags |= JSITER_FOREACH;
sawDeprecatedForEach = true;
addTelemetry(JSCompartment::DeprecatedForEach);
if (versionNumber() < JSVERSION_LATEST) {
if (!report(ParseWarning, pc->sc->strict, pn2, JSMSG_DEPRECATED_FOR_EACH))
return null();
@ -8384,48 +8376,12 @@ Parser<ParseHandler>::exprInParens()
template <typename ParseHandler>
void
Parser<ParseHandler>::accumulateTelemetry()
Parser<ParseHandler>::addTelemetry(JSCompartment::DeprecatedLanguageExtension e)
{
JSContext* cx = context->maybeJSContext();
if (!cx)
return;
const char* filename = getFilename();
if (!filename)
return;
bool isAddon = !!cx->compartment()->addonId;
bool isHTTP = strncmp(filename, "http://", 7) == 0 || strncmp(filename, "https://", 8) == 0;
// Only report telemetry for web content, not add-ons or chrome JS.
if (isAddon || !isHTTP)
return;
enum DeprecatedLanguageExtensions {
DeprecatedForEach = 0, // JS 1.6+
DeprecatedDestructuringForIn = 1, // JS 1.7 only
DeprecatedLegacyGenerator = 2, // JS 1.7+
DeprecatedExpressionClosure = 3, // Added in JS 1.8, but not version-gated
DeprecatedLetBlock = 4, // Added in JS 1.7, but not version-gated
DeprecatedLetExpression = 5, // Added in JS 1.7, but not version-gated
};
// Hazard analysis can't tell that the telemetry callbacks don't GC.
JS::AutoSuppressGCAnalysis nogc;
// Call back into Firefox's Telemetry reporter.
int id = JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT;
if (sawDeprecatedForEach)
cx->runtime()->addTelemetry(id, DeprecatedForEach);
if (sawDeprecatedDestructuringForIn)
cx->runtime()->addTelemetry(id, DeprecatedDestructuringForIn);
if (sawDeprecatedLegacyGenerator)
cx->runtime()->addTelemetry(id, DeprecatedLegacyGenerator);
if (sawDeprecatedExpressionClosure)
cx->runtime()->addTelemetry(id, DeprecatedExpressionClosure);
if (sawDeprecatedLetBlock)
cx->runtime()->addTelemetry(id, DeprecatedLetBlock);
if (sawDeprecatedLetExpression)
cx->runtime()->addTelemetry(id, DeprecatedLetExpression);
cx->compartment()->addTelemetry(e);
}
template class Parser<FullParseHandler>;

View File

@ -372,14 +372,6 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
/* Unexpected end of input, i.e. TOK_EOF not at top-level. */
bool isUnexpectedEOF_:1;
/* Used for collecting telemetry on SpiderMonkey's deprecated language extensions. */
bool sawDeprecatedForEach:1;
bool sawDeprecatedDestructuringForIn:1;
bool sawDeprecatedLegacyGenerator:1;
bool sawDeprecatedExpressionClosure:1;
bool sawDeprecatedLetBlock:1;
bool sawDeprecatedLetExpression:1;
typedef typename ParseHandler::Node Node;
typedef typename ParseHandler::DefinitionNode DefinitionNode;
@ -704,7 +696,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
bool asmJS(Node list);
void accumulateTelemetry();
void addTelemetry(JSCompartment::DeprecatedLanguageExtension e);
friend class LegacyCompExprTransplanter;
friend struct BindData<ParseHandler>;

View File

@ -75,12 +75,15 @@ JSCompartment::JSCompartment(Zone *zone, const JS::CompartmentOptions &options =
maybeAlive(true),
jitCompartment_(nullptr)
{
PodArrayZero(sawDeprecatedLanguageExtension);
runtime_->numCompartments++;
MOZ_ASSERT_IF(options.mergeable(), options.invisibleToDebugger());
}
JSCompartment::~JSCompartment()
{
reportTelemetry();
js_delete(jitCompartment_);
js_delete(watchpointMap);
js_delete(scriptCountsMap);
@ -814,3 +817,20 @@ JSCompartment::addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
*regexpCompartment += regExps.sizeOfExcludingThis(mallocSizeOf);
*savedStacksSet += savedStacks_.sizeOfExcludingThis(mallocSizeOf);
}
void
JSCompartment::reportTelemetry()
{
// Only report telemetry for web content, not add-ons or chrome JS.
if (addonId || isSystem)
return;
// Hazard analysis can't tell that the telemetry callbacks don't GC.
JS::AutoSuppressGCAnalysis nogc;
// Call back into Firefox's Telemetry reporter.
for (size_t i = 0; i < DeprecatedLanguageExtensionCount; i++) {
if (sawDeprecatedLanguageExtension[i])
runtime_->addTelemetry(JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, i);
}
}

View File

@ -519,6 +519,27 @@ struct JSCompartment
js::jit::JitCompartment *jitCompartment() {
return jitCompartment_;
}
enum DeprecatedLanguageExtension {
DeprecatedForEach = 0, // JS 1.6+
DeprecatedDestructuringForIn = 1, // JS 1.7 only
DeprecatedLegacyGenerator = 2, // JS 1.7+
DeprecatedExpressionClosure = 3, // Added in JS 1.8
DeprecatedLetBlock = 4, // Added in JS 1.7
DeprecatedLetExpression = 5, // Added in JS 1.7
DeprecatedLanguageExtensionCount
};
private:
// Used for collecting telemetry on SpiderMonkey's deprecated language extensions.
bool sawDeprecatedLanguageExtension[DeprecatedLanguageExtensionCount];
void reportTelemetry();
public:
void addTelemetry(DeprecatedLanguageExtension e) {
sawDeprecatedLanguageExtension[e] = true;
}
};
inline bool

View File

@ -3039,7 +3039,6 @@ AccumulateTelemetryCallback(int id, uint32_t sample, const char *key)
Telemetry::Accumulate(Telemetry::GC_SCC_SWEEP_MAX_PAUSE_MS, sample);
break;
case JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT:
MOZ_ASSERT(sample <= 5);
Telemetry::Accumulate(Telemetry::JS_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT, sample);
break;
case JS_TELEMETRY_ADDON_EXCEPTIONS: