forked from mirrors/gecko-dev
Bug 1862922 - Run telemetry on day of week support r=arai
Differential Revision: https://phabricator.services.mozilla.com/D193367
This commit is contained in:
parent
8c1e539630
commit
71067c635f
6 changed files with 114 additions and 24 deletions
|
|
@ -71,6 +71,7 @@ custom onunderflow sets an element onunderflow event listener
|
|||
// JavaScript feature usage
|
||||
custom JS_asmjs uses asm.js
|
||||
custom JS_wasm uses WebAssembly
|
||||
custom JS_late_weekday parses a Date with day of week in an unexpected position
|
||||
|
||||
// Console API
|
||||
method console.assert
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ extern JS_PUBLIC_API void JS_SetAccumulateTelemetryCallback(
|
|||
* fixed member of the mozilla::UseCounter enum by the callback.
|
||||
*/
|
||||
|
||||
enum class JSUseCounter { ASMJS, WASM };
|
||||
enum class JSUseCounter { ASMJS, WASM, LATE_WEEKDAY };
|
||||
|
||||
using JSSetUseCounterCallback = void (*)(JSObject*, JSUseCounter);
|
||||
|
||||
|
|
|
|||
|
|
@ -1118,15 +1118,6 @@ static bool TryParseDashedDatePrefix(const CharT* s, size_t length,
|
|||
int* monOut, int* mdayOut) {
|
||||
size_t i = *indexOut;
|
||||
|
||||
if (*monOut != -1) {
|
||||
// If the month has already been set by ParseDate, we'll be at a '-', we
|
||||
// can skip it and start parsing the mday
|
||||
if (i >= length || s[i] != '-') {
|
||||
return false;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
size_t pre = i;
|
||||
size_t mday;
|
||||
if (!ParseDigitsNOrLess(6, &mday, s, &i, length)) {
|
||||
|
|
@ -1355,7 +1346,8 @@ constexpr size_t MinKeywordLength(const CharsAndAction (&keywords)[N]) {
|
|||
|
||||
template <typename CharT>
|
||||
static bool ParseDate(DateTimeInfo::ForceUTC forceUTC, const CharT* s,
|
||||
size_t length, ClippedTime* result) {
|
||||
size_t length, ClippedTime* result,
|
||||
bool* countLateWeekday) {
|
||||
if (length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1369,7 +1361,7 @@ static bool ParseDate(DateTimeInfo::ForceUTC forceUTC, const CharT* s,
|
|||
bool seenMonthName = false;
|
||||
|
||||
// Before we begin, we need to scrub any words from the beginning of the
|
||||
// string that are not a month name
|
||||
// string up to the first number, recording the month if we encounter it
|
||||
for (; index < length; index++) {
|
||||
int c = s[index];
|
||||
|
||||
|
|
@ -1403,11 +1395,6 @@ static bool ParseDate(DateTimeInfo::ForceUTC forceUTC, const CharT* s,
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (seenMonthName) {
|
||||
// If we've found the month name, we're done with this loop, otherwise we
|
||||
// move on to the next word
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index >= length) {
|
||||
|
|
@ -1430,6 +1417,8 @@ static bool ParseDate(DateTimeInfo::ForceUTC forceUTC, const CharT* s,
|
|||
bool negativeYear = false;
|
||||
// Includes "GMT", "UTC", "UT", and "Z" timezone keywords
|
||||
bool seenGmtAbbr = false;
|
||||
// For telemetry purposes
|
||||
bool seenLateWeekday = false;
|
||||
|
||||
// Try parsing the leading dashed-date.
|
||||
//
|
||||
|
|
@ -1676,6 +1665,7 @@ static bool ParseDate(DateTimeInfo::ForceUTC forceUTC, const CharT* s,
|
|||
// Completely ignore days of the week, and don't derive any semantics
|
||||
// from them.
|
||||
if (action == 0) {
|
||||
seenLateWeekday = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1845,16 +1835,38 @@ static bool ParseDate(DateTimeInfo::ForceUTC forceUTC, const CharT* s,
|
|||
date += tzOffset * msPerMinute;
|
||||
}
|
||||
|
||||
// Setting this down here so that it only counts the telemetry in
|
||||
// the case of a successful parse.
|
||||
if (seenLateWeekday) {
|
||||
*countLateWeekday = true;
|
||||
}
|
||||
|
||||
*result = TimeClip(date);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ParseDate(DateTimeInfo::ForceUTC forceUTC, JSLinearString* s,
|
||||
ClippedTime* result) {
|
||||
AutoCheckCannotGC nogc;
|
||||
return s->hasLatin1Chars()
|
||||
? ParseDate(forceUTC, s->latin1Chars(nogc), s->length(), result)
|
||||
: ParseDate(forceUTC, s->twoByteChars(nogc), s->length(), result);
|
||||
ClippedTime* result, JSContext* cx) {
|
||||
bool countLateWeekday = false;
|
||||
bool success;
|
||||
|
||||
{
|
||||
AutoCheckCannotGC nogc;
|
||||
success = s->hasLatin1Chars()
|
||||
? ParseDate(forceUTC, s->latin1Chars(nogc), s->length(),
|
||||
result, &countLateWeekday)
|
||||
: ParseDate(forceUTC, s->twoByteChars(nogc), s->length(),
|
||||
result, &countLateWeekday);
|
||||
}
|
||||
|
||||
// We are running telemetry to see if support for day of week after
|
||||
// mday can be dropped. It is being done here to keep
|
||||
// JSRuntime::setUseCounter out of AutoCheckCannotGC's scope.
|
||||
if (countLateWeekday) {
|
||||
cx->runtime()->setUseCounter(cx->global(), JSUseCounter::LATE_WEEKDAY);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static bool date_parse(JSContext* cx, unsigned argc, Value* vp) {
|
||||
|
|
@ -1876,7 +1888,7 @@ static bool date_parse(JSContext* cx, unsigned argc, Value* vp) {
|
|||
}
|
||||
|
||||
ClippedTime result;
|
||||
if (!ParseDate(ForceUTC(cx->realm()), linearStr, &result)) {
|
||||
if (!ParseDate(ForceUTC(cx->realm()), linearStr, &result, cx)) {
|
||||
args.rval().setNaN();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -3704,7 +3716,7 @@ static bool DateOneArgument(JSContext* cx, const CallArgs& args) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!ParseDate(ForceUTC(cx->realm()), linearStr, &t)) {
|
||||
if (!ParseDate(ForceUTC(cx->realm()), linearStr, &t, cx)) {
|
||||
t = ClippedTime::invalid();
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -2587,6 +2587,9 @@ static void SetUseCounterCallback(JSObject* obj, JSUseCounter counter) {
|
|||
case JSUseCounter::WASM:
|
||||
SetUseCounter(obj, eUseCounter_custom_JS_wasm);
|
||||
break;
|
||||
case JSUseCounter::LATE_WEEKDAY:
|
||||
SetUseCounter(obj, eUseCounter_custom_JS_late_weekday);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected JSUseCounter id");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ support-files = [
|
|||
"browser_promise_userInteractionHandling.html"
|
||||
]
|
||||
|
||||
["browser_date_telemetry.js"]
|
||||
|
||||
["browser_dead_object.js"]
|
||||
|
||||
["browser_exception_leak.js"]
|
||||
|
|
|
|||
72
js/xpconnect/tests/browser/browser_date_telemetry.js
Normal file
72
js/xpconnect/tests/browser/browser_date_telemetry.js
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
const HIST_ID = "USE_COUNTER2_JS_LATE_WEEKDAY_PAGE";
|
||||
|
||||
const triggers = [
|
||||
"Sep 26 Tues 1995",
|
||||
"Sep 26 1995 Tues",
|
||||
"Sep 26 1995 Tues 09:30",
|
||||
"Sep 26 1995 09:Tues:30",
|
||||
"Sep 26 1995 09:30 Tues GMT",
|
||||
"Sep 26 1995 09:30 GMT Tues",
|
||||
|
||||
"26 Tues Sep 1995",
|
||||
"26 Sep Tues 1995",
|
||||
"26 Sep 1995 Tues",
|
||||
|
||||
"1995-09-26 Tues",
|
||||
|
||||
// Multiple occurences should only trigger 1 counter
|
||||
"Sep 26 Tues 1995 Tues",
|
||||
];
|
||||
const nonTriggers = [
|
||||
"Sep 26 1995",
|
||||
"Tues Sep 26 1995",
|
||||
"Sep Tues 26 1995",
|
||||
|
||||
// Invalid format shouldn't trigger the counter
|
||||
"Sep 26 Tues 1995 foo",
|
||||
];
|
||||
|
||||
function getCount() {
|
||||
return Services.telemetry.getHistogramById(HIST_ID).snapshot().sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens and closes a browser tab with minimal JS code which parses
|
||||
* the given Date format.
|
||||
*/
|
||||
async function parseFormat(format, call = "new Date") {
|
||||
let newTab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
`data:text/html;charset=utf-8,<script>${call}("${format}")</script>`
|
||||
);
|
||||
BrowserTestUtils.removeTab(newTab);
|
||||
}
|
||||
|
||||
add_task(async function test_date_telemetry() {
|
||||
let sum = getCount();
|
||||
|
||||
// waitForCondition cannot be used to test if nothing has changed,
|
||||
// so these tests aren't as reliable as the ones in the next loop.
|
||||
// If you encounter an inexplicable failure in any of these tests,
|
||||
// debug by adding a delay to the end of the parseFormat function.
|
||||
for (const format of nonTriggers) {
|
||||
await parseFormat(format);
|
||||
const count = getCount();
|
||||
is(count, sum, `${format} should not trigger telemetry`);
|
||||
sum = count;
|
||||
}
|
||||
|
||||
for (const [i, format] of triggers.entries()) {
|
||||
// Alternate between Date constructor and Date.parse
|
||||
await parseFormat(format, ["new Date", "Date.parse"][i % 2]);
|
||||
await BrowserTestUtils.waitForCondition(() => getCount() > sum);
|
||||
const count = getCount();
|
||||
is(count, sum + 1, `${format} should trigger telemetry`);
|
||||
sum = count;
|
||||
}
|
||||
});
|
||||
Loading…
Reference in a new issue