1 <!DOCTYPE html> 2 <!-- 3 Copyright 2015 The Chromium Authors. All rights reserved. 4 Use of this source code is governed by a BSD-style license that can be 5 found in the LICENSE file. 6 --> 7 <link rel="import" href="/tracing/base/iteration_helpers.html"> 8 <link rel="import" href="/tracing/metrics/system_health/loading_metric.html"> 9 <link rel="import" href="/tracing/mre/function_handle.html"> 10 <link rel="import" href="/tracing/value/value_set.html"> 11 12 <script> 13 'use strict'; 14 15 16 tr.exportTo('tr.mre', function() { 17 function v8CallStatsDump(result, model) { 18 var v8_runtime_map = {}; 19 var totalCount = 0; 20 var totalTime = 0; 21 var values = new tr.v.ValueSet(); 22 23 tr.metrics.sh.loadingMetric(values, model); 24 var ttiEntries = values.valueDicts.filter( 25 (dict) => dict.name === 'timeToFirstInteractive'); 26 var numeric = ttiEntries[0].numeric; 27 if (numeric.running.count > 1) { 28 throw 'Unable to work with a trace that has more than one navigation'; 29 } 30 31 var binsWithSampleDiagnosticMaps = numeric.centralBins.filter( 32 (bin) => bin.diagnosticMaps.length > 0); 33 var diagnostic = binsWithSampleDiagnosticMaps[0] 34 .diagnosticMaps[0]['breakdown']; 35 36 var tti = diagnostic.value.interactive; 37 38 for (var event of model.getDescendantEvents()) { 39 if (!(event instanceof tr.model.ThreadSlice) || event.start > tti) 40 continue; 41 var v8_runtime = event.args['runtime-call-stats']; 42 43 // For older traces, check if we had an arg called 'runtime-call-stat' 44 // instead. 45 if (v8_runtime === undefined) 46 v8_runtime = event.args['runtime-call-stat']; 47 48 if (v8_runtime !== undefined) { 49 try { 50 var v8_runtime_object = JSON.parse(v8_runtime); 51 for (var runtime_call in v8_runtime_object) { 52 // exclude "END" and malformed entries. 53 if (v8_runtime_object[runtime_call].length == 2) { 54 if (v8_runtime_map[runtime_call] === undefined) { 55 v8_runtime_map[runtime_call] = {count: 0, time: 0}; 56 } 57 var runtime_count = v8_runtime_object[runtime_call][0]; 58 v8_runtime_map[runtime_call].count += runtime_count; 59 var runtime_time = v8_runtime_object[runtime_call][1] / 1000; 60 v8_runtime_map[runtime_call].time += runtime_time; 61 totalCount += runtime_count; 62 totalTime += runtime_time; 63 } 64 } 65 } catch (e) { 66 console.warn(e); 67 } 68 } 69 } 70 for (var i in v8_runtime_map) { 71 result.addPair(i, {time: Number(v8_runtime_map[i].time).toFixed(2), 72 count: v8_runtime_map[i].count}); 73 } 74 result.addPair('Total', {time: Number(totalTime).toFixed(2), 75 count: totalCount}); 76 } 77 78 tr.mre.FunctionRegistry.register(v8CallStatsDump); 79 80 // Exporting for tests. 81 return { 82 v8CallStatsDump: v8CallStatsDump 83 }; 84 }); 85 86 </script> 87