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
|
// JavaScript feature usage
|
||||||
custom JS_asmjs uses asm.js
|
custom JS_asmjs uses asm.js
|
||||||
custom JS_wasm uses WebAssembly
|
custom JS_wasm uses WebAssembly
|
||||||
|
custom JS_late_weekday parses a Date with day of week in an unexpected position
|
||||||
|
|
||||||
// Console API
|
// Console API
|
||||||
method console.assert
|
method console.assert
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ extern JS_PUBLIC_API void JS_SetAccumulateTelemetryCallback(
|
||||||
* fixed member of the mozilla::UseCounter enum by the callback.
|
* 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);
|
using JSSetUseCounterCallback = void (*)(JSObject*, JSUseCounter);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1118,15 +1118,6 @@ static bool TryParseDashedDatePrefix(const CharT* s, size_t length,
|
||||||
int* monOut, int* mdayOut) {
|
int* monOut, int* mdayOut) {
|
||||||
size_t i = *indexOut;
|
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 pre = i;
|
||||||
size_t mday;
|
size_t mday;
|
||||||
if (!ParseDigitsNOrLess(6, &mday, s, &i, length)) {
|
if (!ParseDigitsNOrLess(6, &mday, s, &i, length)) {
|
||||||
|
|
@ -1355,7 +1346,8 @@ constexpr size_t MinKeywordLength(const CharsAndAction (&keywords)[N]) {
|
||||||
|
|
||||||
template <typename CharT>
|
template <typename CharT>
|
||||||
static bool ParseDate(DateTimeInfo::ForceUTC forceUTC, const CharT* s,
|
static bool ParseDate(DateTimeInfo::ForceUTC forceUTC, const CharT* s,
|
||||||
size_t length, ClippedTime* result) {
|
size_t length, ClippedTime* result,
|
||||||
|
bool* countLateWeekday) {
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -1369,7 +1361,7 @@ static bool ParseDate(DateTimeInfo::ForceUTC forceUTC, const CharT* s,
|
||||||
bool seenMonthName = false;
|
bool seenMonthName = false;
|
||||||
|
|
||||||
// Before we begin, we need to scrub any words from the beginning of the
|
// 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++) {
|
for (; index < length; index++) {
|
||||||
int c = s[index];
|
int c = s[index];
|
||||||
|
|
||||||
|
|
@ -1403,11 +1395,6 @@ static bool ParseDate(DateTimeInfo::ForceUTC forceUTC, const CharT* s,
|
||||||
break;
|
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) {
|
if (index >= length) {
|
||||||
|
|
@ -1430,6 +1417,8 @@ static bool ParseDate(DateTimeInfo::ForceUTC forceUTC, const CharT* s,
|
||||||
bool negativeYear = false;
|
bool negativeYear = false;
|
||||||
// Includes "GMT", "UTC", "UT", and "Z" timezone keywords
|
// Includes "GMT", "UTC", "UT", and "Z" timezone keywords
|
||||||
bool seenGmtAbbr = false;
|
bool seenGmtAbbr = false;
|
||||||
|
// For telemetry purposes
|
||||||
|
bool seenLateWeekday = false;
|
||||||
|
|
||||||
// Try parsing the leading dashed-date.
|
// 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
|
// Completely ignore days of the week, and don't derive any semantics
|
||||||
// from them.
|
// from them.
|
||||||
if (action == 0) {
|
if (action == 0) {
|
||||||
|
seenLateWeekday = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1845,16 +1835,38 @@ static bool ParseDate(DateTimeInfo::ForceUTC forceUTC, const CharT* s,
|
||||||
date += tzOffset * msPerMinute;
|
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);
|
*result = TimeClip(date);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ParseDate(DateTimeInfo::ForceUTC forceUTC, JSLinearString* s,
|
static bool ParseDate(DateTimeInfo::ForceUTC forceUTC, JSLinearString* s,
|
||||||
ClippedTime* result) {
|
ClippedTime* result, JSContext* cx) {
|
||||||
|
bool countLateWeekday = false;
|
||||||
|
bool success;
|
||||||
|
|
||||||
|
{
|
||||||
AutoCheckCannotGC nogc;
|
AutoCheckCannotGC nogc;
|
||||||
return s->hasLatin1Chars()
|
success = s->hasLatin1Chars()
|
||||||
? ParseDate(forceUTC, s->latin1Chars(nogc), s->length(), result)
|
? ParseDate(forceUTC, s->latin1Chars(nogc), s->length(),
|
||||||
: ParseDate(forceUTC, s->twoByteChars(nogc), s->length(), result);
|
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) {
|
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;
|
ClippedTime result;
|
||||||
if (!ParseDate(ForceUTC(cx->realm()), linearStr, &result)) {
|
if (!ParseDate(ForceUTC(cx->realm()), linearStr, &result, cx)) {
|
||||||
args.rval().setNaN();
|
args.rval().setNaN();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -3704,7 +3716,7 @@ static bool DateOneArgument(JSContext* cx, const CallArgs& args) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ParseDate(ForceUTC(cx->realm()), linearStr, &t)) {
|
if (!ParseDate(ForceUTC(cx->realm()), linearStr, &t, cx)) {
|
||||||
t = ClippedTime::invalid();
|
t = ClippedTime::invalid();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -2587,6 +2587,9 @@ static void SetUseCounterCallback(JSObject* obj, JSUseCounter counter) {
|
||||||
case JSUseCounter::WASM:
|
case JSUseCounter::WASM:
|
||||||
SetUseCounter(obj, eUseCounter_custom_JS_wasm);
|
SetUseCounter(obj, eUseCounter_custom_JS_wasm);
|
||||||
break;
|
break;
|
||||||
|
case JSUseCounter::LATE_WEEKDAY:
|
||||||
|
SetUseCounter(obj, eUseCounter_custom_JS_late_weekday);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
MOZ_ASSERT_UNREACHABLE("Unexpected JSUseCounter id");
|
MOZ_ASSERT_UNREACHABLE("Unexpected JSUseCounter id");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ support-files = [
|
||||||
"browser_promise_userInteractionHandling.html"
|
"browser_promise_userInteractionHandling.html"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
["browser_date_telemetry.js"]
|
||||||
|
|
||||||
["browser_dead_object.js"]
|
["browser_dead_object.js"]
|
||||||
|
|
||||||
["browser_exception_leak.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