11cb0ef41Sopenharmony_ci// Copyright 2018 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci(() => { 61cb0ef41Sopenharmony_ci let all_profiles = []; 71cb0ef41Sopenharmony_ci let instanceMap = new WeakMap(); 81cb0ef41Sopenharmony_ci let instanceCounter = 0; 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci function instrument(imports, profile) { 111cb0ef41Sopenharmony_ci let orig_imports = imports; 121cb0ef41Sopenharmony_ci return new Proxy(imports, { 131cb0ef41Sopenharmony_ci get: (obj, module_name) => { 141cb0ef41Sopenharmony_ci let orig_module = orig_imports[module_name]; 151cb0ef41Sopenharmony_ci return new Proxy(orig_module, { 161cb0ef41Sopenharmony_ci get: (obj, item_name) => { 171cb0ef41Sopenharmony_ci let orig_func = orig_module[item_name]; 181cb0ef41Sopenharmony_ci let item = orig_func; 191cb0ef41Sopenharmony_ci if (typeof orig_func == "function") { 201cb0ef41Sopenharmony_ci var full_name = module_name + "." + item_name; 211cb0ef41Sopenharmony_ci print("instrumented " + full_name); 221cb0ef41Sopenharmony_ci profile[full_name] = {name: full_name, count: 0, total: 0}; 231cb0ef41Sopenharmony_ci item = function profiled_func(...args) { 241cb0ef41Sopenharmony_ci var before = performance.now(); 251cb0ef41Sopenharmony_ci var result = orig_func(...args); 261cb0ef41Sopenharmony_ci var delta = performance.now() - before; 271cb0ef41Sopenharmony_ci var data = profile[full_name]; 281cb0ef41Sopenharmony_ci data.count++; 291cb0ef41Sopenharmony_ci data.total += delta; 301cb0ef41Sopenharmony_ci return result; 311cb0ef41Sopenharmony_ci } 321cb0ef41Sopenharmony_ci } 331cb0ef41Sopenharmony_ci return item; 341cb0ef41Sopenharmony_ci } 351cb0ef41Sopenharmony_ci }) 361cb0ef41Sopenharmony_ci } 371cb0ef41Sopenharmony_ci }); 381cb0ef41Sopenharmony_ci } 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci function dumpProfile(profile) { 411cb0ef41Sopenharmony_ci let array = []; 421cb0ef41Sopenharmony_ci for (let key in profile) { 431cb0ef41Sopenharmony_ci if (key == "instanceNum") continue; 441cb0ef41Sopenharmony_ci let data = profile[key]; 451cb0ef41Sopenharmony_ci if (data.count == 0) continue; 461cb0ef41Sopenharmony_ci array.push(data); 471cb0ef41Sopenharmony_ci } 481cb0ef41Sopenharmony_ci print(`--- Import profile for instance ${profile.instanceNum} ---`); 491cb0ef41Sopenharmony_ci if (array.length == 0) return; 501cb0ef41Sopenharmony_ci array.sort((a, b) => b.total - a.total); 511cb0ef41Sopenharmony_ci for (let data of array) { 521cb0ef41Sopenharmony_ci print(`${padl(data.name, 30)}: ${padr(data.count, 10)} ${padp(data.total, 10)}ms`); 531cb0ef41Sopenharmony_ci } 541cb0ef41Sopenharmony_ci } 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci function padl(s, len) { 571cb0ef41Sopenharmony_ci s = s.toString(); 581cb0ef41Sopenharmony_ci while (s.length < len) s = s + " "; 591cb0ef41Sopenharmony_ci return s; 601cb0ef41Sopenharmony_ci } 611cb0ef41Sopenharmony_ci function padr(s, len) { 621cb0ef41Sopenharmony_ci s = s.toString(); 631cb0ef41Sopenharmony_ci while (s.length < len) s = " " + s; 641cb0ef41Sopenharmony_ci return s; 651cb0ef41Sopenharmony_ci } 661cb0ef41Sopenharmony_ci function padp(s, len) { 671cb0ef41Sopenharmony_ci s = s.toString(); 681cb0ef41Sopenharmony_ci var i = s.indexOf("."); 691cb0ef41Sopenharmony_ci if (i == -1) i = s.length; 701cb0ef41Sopenharmony_ci while (i++ < len) s = " " + s; 711cb0ef41Sopenharmony_ci return s; 721cb0ef41Sopenharmony_ci } 731cb0ef41Sopenharmony_ci 741cb0ef41Sopenharmony_ci // patch: WebAssembly.instantiate (async) 751cb0ef41Sopenharmony_ci let orig_instantiate = WebAssembly.instantiate; 761cb0ef41Sopenharmony_ci WebAssembly.instantiate = (m, imports, ...args) => { 771cb0ef41Sopenharmony_ci let profile = {}; 781cb0ef41Sopenharmony_ci let promise = orig_instantiate(m, instrument(imports, profile), ...args); 791cb0ef41Sopenharmony_ci promise.then((instance) => { 801cb0ef41Sopenharmony_ci instanceMap.set(instance, profile); 811cb0ef41Sopenharmony_ci all_profiles.push(profile); 821cb0ef41Sopenharmony_ci profile.instanceNum = instanceCounter++; 831cb0ef41Sopenharmony_ci }); 841cb0ef41Sopenharmony_ci return promise; 851cb0ef41Sopenharmony_ci } 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci // patch: new WebAssembly.Instance (sync) 881cb0ef41Sopenharmony_ci let orig_new_instance = WebAssembly.Instance; 891cb0ef41Sopenharmony_ci WebAssembly.Instance = new Proxy(orig_new_instance, { 901cb0ef41Sopenharmony_ci construct: (target, args) => { 911cb0ef41Sopenharmony_ci let profile = {}; 921cb0ef41Sopenharmony_ci args[1] = instrument(args[1], profile); 931cb0ef41Sopenharmony_ci let instance = new orig_new_instance(...args); 941cb0ef41Sopenharmony_ci instanceMap.set(instance, profile); 951cb0ef41Sopenharmony_ci all_profiles.push(profile); 961cb0ef41Sopenharmony_ci profile.instanceNum = instanceCounter++; 971cb0ef41Sopenharmony_ci return instance; 981cb0ef41Sopenharmony_ci } 991cb0ef41Sopenharmony_ci }); 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci // expose: WebAssembly.dumpProfile(instance) 1021cb0ef41Sopenharmony_ci WebAssembly.dumpProfile = (instance) => { 1031cb0ef41Sopenharmony_ci let profile = instanceMap.get(instance); 1041cb0ef41Sopenharmony_ci if (profile === undefined) return; 1051cb0ef41Sopenharmony_ci dumpProfile(profile); 1061cb0ef41Sopenharmony_ci } 1071cb0ef41Sopenharmony_ci // expose: WebAssembly.clearProfile(instance) 1081cb0ef41Sopenharmony_ci WebAssembly.clearProfile = (instance) => { 1091cb0ef41Sopenharmony_ci let profile = instanceMap.get(instance); 1101cb0ef41Sopenharmony_ci if (profile === undefined) return; 1111cb0ef41Sopenharmony_ci for (let key in profile) { 1121cb0ef41Sopenharmony_ci if (key == "instanceNum") continue; 1131cb0ef41Sopenharmony_ci let data = p[key]; 1141cb0ef41Sopenharmony_ci data.count = 0; 1151cb0ef41Sopenharmony_ci data.total = 0; 1161cb0ef41Sopenharmony_ci } 1171cb0ef41Sopenharmony_ci } 1181cb0ef41Sopenharmony_ci // expose: WebAssembly.dumpAllProfiles() 1191cb0ef41Sopenharmony_ci WebAssembly.dumpAllProfiles = () => { 1201cb0ef41Sopenharmony_ci for (let profile of all_profiles) dumpProfile(profile); 1211cb0ef41Sopenharmony_ci } 1221cb0ef41Sopenharmony_ci // expose: WebAssembly.getProfile(instance) 1231cb0ef41Sopenharmony_ci // returns: { 1241cb0ef41Sopenharmony_ci // func_name1: {name: func_name1, count: <num>, total: <num>} 1251cb0ef41Sopenharmony_ci // func_name2: {name: func_name1, count: <num>, total: <num>} 1261cb0ef41Sopenharmony_ci // ... 1271cb0ef41Sopenharmony_ci // } 1281cb0ef41Sopenharmony_ci WebAssembly.getProfile = (instance) => { 1291cb0ef41Sopenharmony_ci return instanceMap.get(instance); 1301cb0ef41Sopenharmony_ci } 1311cb0ef41Sopenharmony_ci})(); 132