| <!DOCTYPE html> |
| <!-- |
| Copyright 2015 The Chromium Authors. All rights reserved. |
| Use of this source code is governed by a BSD-style license that can be |
| found in the LICENSE file. |
| --> |
| <link rel="import" href="/tracing/base/iteration_helpers.html"> |
| <link rel="import" href="/tracing/metrics/system_health/loading_metric.html"> |
| <link rel="import" href="/tracing/mre/function_handle.html"> |
| <link rel="import" href="/tracing/value/value_set.html"> |
| |
| <script> |
| 'use strict'; |
| |
| |
| tr.exportTo('tr.mre', function() { |
| function v8CallStatsDump(result, model) { |
| var v8_runtime_map = {}; |
| var totalCount = 0; |
| var totalTime = 0; |
| var values = new tr.v.ValueSet(); |
| |
| tr.metrics.sh.loadingMetric(values, model); |
| var ttiEntries = values.valueDicts.filter( |
| (dict) => dict.name === 'timeToFirstInteractive'); |
| var numeric = ttiEntries[0].numeric; |
| if (numeric.running.count > 1) { |
| throw 'Unable to work with a trace that has more than one navigation'; |
| } |
| |
| var binsWithSampleDiagnosticMaps = numeric.centralBins.filter( |
| (bin) => bin.diagnosticMaps.length > 0); |
| var diagnostic = binsWithSampleDiagnosticMaps[0] |
| .diagnosticMaps[0]['breakdown']; |
| |
| var tti = diagnostic.value.interactive; |
| |
| for (var event of model.getDescendantEvents()) { |
| if (!(event instanceof tr.model.ThreadSlice) || event.start > tti) |
| continue; |
| var v8_runtime = event.args['runtime-call-stats']; |
| |
| // For older traces, check if we had an arg called 'runtime-call-stat' |
| // instead. |
| if (v8_runtime === undefined) |
| v8_runtime = event.args['runtime-call-stat']; |
| |
| if (v8_runtime !== undefined) { |
| try { |
| var v8_runtime_object = JSON.parse(v8_runtime); |
| for (var runtime_call in v8_runtime_object) { |
| // exclude "END" and malformed entries. |
| if (v8_runtime_object[runtime_call].length == 2) { |
| if (v8_runtime_map[runtime_call] === undefined) { |
| v8_runtime_map[runtime_call] = {count: 0, time: 0}; |
| } |
| var runtime_count = v8_runtime_object[runtime_call][0]; |
| v8_runtime_map[runtime_call].count += runtime_count; |
| var runtime_time = v8_runtime_object[runtime_call][1] / 1000; |
| v8_runtime_map[runtime_call].time += runtime_time; |
| totalCount += runtime_count; |
| totalTime += runtime_time; |
| } |
| } |
| } catch (e) { |
| console.warn(e); |
| } |
| } |
| } |
| for (var i in v8_runtime_map) { |
| result.addPair(i, {time: Number(v8_runtime_map[i].time).toFixed(2), |
| count: v8_runtime_map[i].count}); |
| } |
| result.addPair('Total', {time: Number(totalTime).toFixed(2), |
| count: totalCount}); |
| } |
| |
| tr.mre.FunctionRegistry.register(v8CallStatsDump); |
| |
| // Exporting for tests. |
| return { |
| v8CallStatsDump: v8CallStatsDump |
| }; |
| }); |
| |
| </script> |