Bug 1362114 - JSBC: Add telemetry to later tune the heuristics. r=mrbkap,francois

This commit is contained in:
Nicolas B. Pierron 2017-06-20 09:53:10 +00:00
parent de892834ed
commit c64732dcc7
5 changed files with 257 additions and 0 deletions

View File

@ -31,6 +31,12 @@ enum UseCounter : int16_t {
eUseCounter_Count
};
enum IncCounter : int16_t {
eIncCounter_UNKNOWN = -1,
eIncCounter_ScriptTag,
eIncCounter_Count
};
}
#endif

View File

@ -1374,9 +1374,13 @@ nsIDocument::nsIDocument()
mUseCounters(0),
mChildDocumentUseCounters(0),
mNotifiedPageForUseCounter(0),
mIncCounters(),
mUserHasInteracted(false)
{
SetIsInDocument();
for (auto& cnt : mIncCounters) {
cnt = 0;
}
}
nsDocument::nsDocument(const char* aContentType)
@ -12743,6 +12747,11 @@ nsDocument::ReportUseCounters(UseCounterReportKind aKind)
}
}
}
if (IsContentDocument() || IsResourceDoc()) {
uint16_t num = mIncCounters[eIncCounter_ScriptTag];
Telemetry::Accumulate(Telemetry::DOM_SCRIPT_EVAL_PER_DOCUMENT, num);
}
}
void

View File

@ -2888,6 +2888,11 @@ public:
void PropagateUseCounters(nsIDocument* aParentDocument);
void SetDocumentIncCounter(mozilla::IncCounter aIncCounter, uint32_t inc = 1)
{
mIncCounters[aIncCounter] += inc;
}
void SetUserHasInteracted(bool aUserHasInteracted)
{
mUserHasInteracted = aUserHasInteracted;
@ -3428,6 +3433,9 @@ protected:
// for this child document.
std::bitset<mozilla::eUseCounter_Count> mNotifiedPageForUseCounter;
// Count the number of times something is seen in a document.
mozilla::Array<uint16_t, mozilla::eIncCounter_Count> mIncCounters;
// Whether the user has interacted with the document or not:
bool mUserHasInteracted;

View File

@ -175,6 +175,59 @@ ScriptLoader::~ScriptLoader()
}
}
// Collect telemtry data about the cache information, and the kind of source
// which are being loaded, and where it is being loaded from.
static void
CollectScriptTelemetry(nsIIncrementalStreamLoader* aLoader,
ScriptLoadRequest* aRequest)
{
using namespace mozilla::Telemetry;
// Skip this function if we are not running telemetry.
if (!CanRecordExtended()) {
return;
}
// Report the type of source, as well as the size of the source.
if (aRequest->IsLoadingSource()) {
if (aRequest->mIsInline) {
AccumulateCategorical(LABELS_DOM_SCRIPT_LOADING_SOURCE::Inline);
nsAutoString inlineData;
aRequest->mElement->GetScriptText(inlineData);
Accumulate(DOM_SCRIPT_INLINE_SIZE, inlineData.Length());
} else {
AccumulateCategorical(LABELS_DOM_SCRIPT_LOADING_SOURCE::SourceFallback);
Accumulate(DOM_SCRIPT_SOURCE_SIZE, aRequest->mScriptText.length());
}
} else {
MOZ_ASSERT(aRequest->IsLoading());
if (aRequest->IsSource()) {
AccumulateCategorical(LABELS_DOM_SCRIPT_LOADING_SOURCE::Source);
Accumulate(DOM_SCRIPT_SOURCE_SIZE, aRequest->mScriptText.length());
} else {
MOZ_ASSERT(aRequest->IsBytecode());
AccumulateCategorical(LABELS_DOM_SCRIPT_LOADING_SOURCE::AltData);
Accumulate(DOM_SCRIPT_BYTECODE_SIZE, aRequest->mScriptBytecode.length());
}
}
// Skip if we do not have any cache information for the given script.
if (!aLoader) {
return;
}
nsCOMPtr<nsIRequest> channel;
aLoader->GetRequest(getter_AddRefs(channel));
nsCOMPtr<nsICacheInfoChannel> cic(do_QueryInterface(channel));
if (!cic) {
return;
}
int32_t fetchCount = 0;
if (NS_SUCCEEDED(cic->GetCacheTokenFetchCount(&fetchCount))) {
Accumulate(DOM_SCRIPT_FETCH_COUNT, fetchCount);
}
}
// Helper method for checking if the script element is an event-handler
// This means that it has both a for-attribute and a event-attribute.
// Also, if the for-attribute has a value that matches "\s*window\s*",
@ -1364,6 +1417,7 @@ ScriptLoader::ProcessScriptElement(nsIScriptElement* aElement)
request->mProgress = ScriptLoadRequest::Progress::Loading_Source;
request->mDataType = ScriptLoadRequest::DataType::Source;
TRACE_FOR_TEST_BOOL(request->mElement, "scriptloader_load_source");
CollectScriptTelemetry(nullptr, request);
if (request->IsModuleRequest()) {
ModuleLoadRequest* modReq = request->AsModuleRequest();
@ -2002,6 +2056,7 @@ ScriptLoader::ShouldCacheBytecode(ScriptLoadRequest* aRequest)
nsresult
ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest)
{
using namespace mozilla::Telemetry;
MOZ_ASSERT(aRequest->IsReadyToRun());
// We need a document to evaluate scripts.
@ -2016,6 +2071,9 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest)
return NS_ERROR_FAILURE;
}
// Report telemetry results of the number of scripts evaluated.
mDocument->SetDocumentIncCounter(IncCounter::eIncCounter_ScriptTag);
// Get the script-type to be used by this element.
NS_ASSERTION(scriptContent, "no content - what is default script-type?");
@ -2081,9 +2139,11 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest)
nsJSUtils::ExecutionContext exec(aes.cx(), global);
if (aRequest->mOffThreadToken) {
LOG(("ScriptLoadRequest (%p): Decode Bytecode & Join and Execute", aRequest));
AutoTimer<DOM_SCRIPT_OFF_THREAD_DECODE_EXEC_MS> timer;
rv = exec.DecodeJoinAndExec(&aRequest->mOffThreadToken);
} else {
LOG(("ScriptLoadRequest (%p): Decode Bytecode and Execute", aRequest));
AutoTimer<DOM_SCRIPT_MAIN_THREAD_DECODE_EXEC_MS> timer;
rv = exec.DecodeAndExec(options, aRequest->mScriptBytecode,
aRequest->mBytecodeOffset);
}
@ -2095,6 +2155,14 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest)
JS::Rooted<JSScript*> script(aes.cx());
bool encodeBytecode = ShouldCacheBytecode(aRequest);
TimeStamp start;
if (Telemetry::CanRecordExtended()) {
// Only record telemetry for scripts which are above the threshold.
if (aRequest->mCacheInfo && aRequest->mScriptText.length() < 1024) {
start = TimeStamp::Now();
}
}
{
nsJSUtils::ExecutionContext exec(aes.cx(), global);
exec.SetEncodeBytecode(encodeBytecode);
@ -2104,12 +2172,24 @@ ScriptLoader::EvaluateScript(ScriptLoadRequest* aRequest)
LOG(("ScriptLoadRequest (%p): Join (off-thread parsing) and Execute",
aRequest));
rv = exec.JoinAndExec(&aRequest->mOffThreadToken, &script);
if (start) {
AccumulateTimeDelta(encodeBytecode
? DOM_SCRIPT_OFF_THREAD_PARSE_ENCODE_EXEC_MS
: DOM_SCRIPT_OFF_THREAD_PARSE_EXEC_MS,
start);
}
} else {
// Main thread parsing (inline and small scripts)
LOG(("ScriptLoadRequest (%p): Compile And Exec", aRequest));
nsAutoString inlineData;
SourceBufferHolder srcBuf = GetScriptSource(aRequest, inlineData);
rv = exec.CompileAndExec(options, srcBuf, &script);
if (start) {
AccumulateTimeDelta(encodeBytecode
? DOM_SCRIPT_MAIN_THREAD_PARSE_ENCODE_EXEC_MS
: DOM_SCRIPT_MAIN_THREAD_PARSE_EXEC_MS,
start);
}
}
}
@ -2210,6 +2290,7 @@ ScriptLoader::EncodeBytecode()
return;
}
Telemetry::AutoTimer<Telemetry::DOM_SCRIPT_ENCODING_MS_PER_DOCUMENT> timer;
AutoEntryScript aes(globalObject, "encode bytecode", true);
RefPtr<ScriptLoadRequest> request;
while (!mBytecodeEncodingQueue.isEmpty()) {
@ -2223,6 +2304,7 @@ ScriptLoader::EncodeBytecode()
void
ScriptLoader::EncodeRequestBytecode(JSContext* aCx, ScriptLoadRequest* aRequest)
{
using namespace mozilla::Telemetry;
nsresult rv = NS_OK;
MOZ_ASSERT(aRequest->mCacheInfo);
auto bytecodeFailed = mozilla::MakeScopeExit([&]() {
@ -2233,12 +2315,14 @@ ScriptLoader::EncodeRequestBytecode(JSContext* aCx, ScriptLoadRequest* aRequest)
if (!JS::FinishIncrementalEncoding(aCx, script, aRequest->mScriptBytecode)) {
LOG(("ScriptLoadRequest (%p): Cannot serialize bytecode",
aRequest));
AccumulateCategorical(LABELS_DOM_SCRIPT_ENCODING_STATUS::EncodingFailure);
return;
}
if (aRequest->mScriptBytecode.length() >= UINT32_MAX) {
LOG(("ScriptLoadRequest (%p): Bytecode cache is too large to be decoded correctly.",
aRequest));
AccumulateCategorical(LABELS_DOM_SCRIPT_ENCODING_STATUS::BufferTooLarge);
return;
}
@ -2251,6 +2335,7 @@ ScriptLoader::EncodeRequestBytecode(JSContext* aCx, ScriptLoadRequest* aRequest)
if (NS_FAILED(rv)) {
LOG(("ScriptLoadRequest (%p): Cannot open bytecode cache (rv = %X, output = %p)",
aRequest, unsigned(rv), output.get()));
AccumulateCategorical(LABELS_DOM_SCRIPT_ENCODING_STATUS::OpenFailure);
return;
}
MOZ_ASSERT(output);
@ -2258,6 +2343,9 @@ ScriptLoader::EncodeRequestBytecode(JSContext* aCx, ScriptLoadRequest* aRequest)
nsresult rv = output->Close();
LOG(("ScriptLoadRequest (%p): Closing (rv = %X)",
aRequest, unsigned(rv)));
if (NS_FAILED(rv)) {
AccumulateCategorical(LABELS_DOM_SCRIPT_ENCODING_STATUS::CloseFailure);
}
});
uint32_t n;
@ -2266,11 +2354,13 @@ ScriptLoader::EncodeRequestBytecode(JSContext* aCx, ScriptLoadRequest* aRequest)
LOG(("ScriptLoadRequest (%p): Write bytecode cache (rv = %X, length = %u, written = %u)",
aRequest, unsigned(rv), unsigned(aRequest->mScriptBytecode.length()), n));
if (NS_FAILED(rv)) {
AccumulateCategorical(LABELS_DOM_SCRIPT_ENCODING_STATUS::WriteFailure);
return;
}
bytecodeFailed.release();
TRACE_FOR_TEST_NONE(aRequest->mElement, "scriptloader_bytecode_saved");
AccumulateCategorical(LABELS_DOM_SCRIPT_ENCODING_STATUS::EncodingSuccess);
}
void
@ -2763,6 +2853,7 @@ ScriptLoader::PrepareLoadedRequest(ScriptLoadRequest* aRequest,
return NS_BINDING_ABORTED;
}
MOZ_ASSERT(aRequest->IsLoading());
CollectScriptTelemetry(aLoader, aRequest);
// If we don't have a document, then we need to abort further
// evaluation.

View File

@ -12425,6 +12425,149 @@
"bug_numbers": [1344152],
"description": "Note the encoding (e.g. 'UTF-8', 'windows-1252', 'ASCII') of each external <script> element that is successfully loaded and decoded."
},
"DOM_SCRIPT_LOADING_SOURCE": {
"record_in_processes": ["content"],
"alert_emails": ["nicolas.b.pierron@mozilla.com"],
"expires_in_version": "58",
"kind": "categorical",
"bug_numbers": [1362114],
"labels": ["Inline", "SourceFallback", "Source", "AltData"],
"description": "Record the input from which the bytes are coming from, for each script in a document."
},
"DOM_SCRIPT_INLINE_SIZE": {
"record_in_processes": ["content"],
"alert_emails": ["nicolas.b.pierron@mozilla.com"],
"expires_in_version": "58",
"kind": "exponential",
"low": 64,
"high": 16000000,
"n_buckets": 50,
"bug_numbers": [1362114],
"description": "Size (in number of characters) of each script which is inlined in a document."
},
"DOM_SCRIPT_SOURCE_SIZE": {
"record_in_processes": ["content"],
"alert_emails": ["nicolas.b.pierron@mozilla.com"],
"expires_in_version": "58",
"kind": "exponential",
"low": 64,
"high": 16000000,
"n_buckets": 50,
"bug_numbers": [1362114],
"description": "Size (in number of characters) of each script which is streamed in plain-text in a document."
},
"DOM_SCRIPT_BYTECODE_SIZE": {
"record_in_processes": ["content"],
"alert_emails": ["nicolas.b.pierron@mozilla.com"],
"expires_in_version": "58",
"kind": "exponential",
"low": 64,
"high": 16000000,
"n_buckets": 50,
"bug_numbers": [1362114],
"description": "Size (in number of bytes) of each script which is streamed in encoded-format in a document."
},
"DOM_SCRIPT_FETCH_COUNT": {
"record_in_processes": ["content"],
"alert_emails": ["nicolas.b.pierron@mozilla.com"],
"expires_in_version": "58",
"kind": "linear",
"low": 1,
"high": 100,
"n_buckets": 99,
"bug_numbers": [1362114],
"description": "For each script in a document, record the number of times it was requested since it got saved in the cache."
},
"DOM_SCRIPT_MAIN_THREAD_PARSE_EXEC_MS": {
"record_in_processes": ["content"],
"alert_emails": ["nicolas.b.pierron@mozilla.com"],
"expires_in_version": "58",
"kind": "exponential",
"high": 50000,
"n_buckets": 100,
"bug_numbers": [1362114],
"description": "Time, in milliseconds, needed to parse and execute a script (which might be encoded later) on the main thread."
},
"DOM_SCRIPT_MAIN_THREAD_PARSE_ENCODE_EXEC_MS": {
"record_in_processes": ["content"],
"alert_emails": ["nicolas.b.pierron@mozilla.com"],
"expires_in_version": "58",
"kind": "exponential",
"high": 50000,
"n_buckets": 100,
"bug_numbers": [1362114],
"description": "Time, in milliseconds, needed to parse, encode and execute a script on the main thread."
},
"DOM_SCRIPT_MAIN_THREAD_DECODE_EXEC_MS": {
"record_in_processes": ["content"],
"alert_emails": ["nicolas.b.pierron@mozilla.com"],
"expires_in_version": "58",
"kind": "exponential",
"high": 50000,
"n_buckets": 100,
"bug_numbers": [1362114],
"description": "Time, in milliseconds, needed to decode and execute a script on the main thread."
},
"DOM_SCRIPT_OFF_THREAD_PARSE_EXEC_MS": {
"record_in_processes": ["content"],
"alert_emails": ["nicolas.b.pierron@mozilla.com"],
"expires_in_version": "58",
"kind": "exponential",
"high": 50000,
"n_buckets": 100,
"bug_numbers": [1362114],
"description": "Time, in milliseconds, needed to parse off-main-thread and execute a script (which might be encoded later) on the main thread."
},
"DOM_SCRIPT_OFF_THREAD_PARSE_ENCODE_EXEC_MS": {
"record_in_processes": ["content"],
"alert_emails": ["nicolas.b.pierron@mozilla.com"],
"expires_in_version": "58",
"kind": "exponential",
"high": 50000,
"n_buckets": 100,
"bug_numbers": [1362114],
"description": "Time, in milliseconds, needed to parse off-main-thread, encode and execute a script on the main thread."
},
"DOM_SCRIPT_OFF_THREAD_DECODE_EXEC_MS": {
"record_in_processes": ["content"],
"alert_emails": ["nicolas.b.pierron@mozilla.com"],
"expires_in_version": "58",
"kind": "exponential",
"high": 50000,
"n_buckets": 100,
"bug_numbers": [1362114],
"description": "Time, in milliseconds, needed to decode off-main-thread and execute a script on the main thread."
},
"DOM_SCRIPT_ENCODING_MS_PER_DOCUMENT": {
"record_in_processes": ["content"],
"alert_emails": ["nicolas.b.pierron@mozilla.com"],
"expires_in_version": "58",
"kind": "linear",
"high": 64,
"n_buckets": 32,
"bug_numbers": [1362114],
"description": "Time, in milliseconds, needed to encode all scripts in a document."
},
"DOM_SCRIPT_ENCODING_STATUS": {
"record_in_processes": ["content"],
"alert_emails": ["nicolas.b.pierron@mozilla.com"],
"expires_in_version": "58",
"kind": "categorical",
"bug_numbers": [1362114],
"labels": ["EncodingFailure", "BufferTooLarge", "OpenFailure", "WriteFailure", "CloseFailure", "EncodingSuccess"],
"description": "Record the failure reasons of the JavaScript Start-up Bytecode Cache encoder."
},
"DOM_SCRIPT_EVAL_PER_DOCUMENT": {
"record_in_processes": ["content"],
"alert_emails": ["nicolas.b.pierron@mozilla.com"],
"expires_in_version": "58",
"kind": "linear",
"low": 1,
"high": 200,
"n_buckets": 50,
"bug_numbers": [1362114],
"description": "Number of script tags evaluated per document."
},
"VIDEO_FASTSEEK_USED": {
"record_in_processes": ["main", "content"],
"alert_emails": ["cpearce@mozilla.com", "tkuo@mozilla.com"],