diff options
Diffstat (limited to 'deps/v8/tools/wasm/wasm-import-profiler.js')
-rw-r--r-- | deps/v8/tools/wasm/wasm-import-profiler.js | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/deps/v8/tools/wasm/wasm-import-profiler.js b/deps/v8/tools/wasm/wasm-import-profiler.js new file mode 100644 index 0000000000..cfbb3fb13b --- /dev/null +++ b/deps/v8/tools/wasm/wasm-import-profiler.js @@ -0,0 +1,131 @@ +// Copyright 2018 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(() => { + let all_profiles = []; + let instanceMap = new WeakMap(); + let instanceCounter = 0; + + function instrument(imports, profile) { + let orig_imports = imports; + return new Proxy(imports, { + get: (obj, module_name) => { + let orig_module = orig_imports[module_name]; + return new Proxy(orig_module, { + get: (obj, item_name) => { + let orig_func = orig_module[item_name]; + let item = orig_func; + if (typeof orig_func == "function") { + var full_name = module_name + "." + item_name; + print("instrumented " + full_name); + profile[full_name] = {name: full_name, count: 0, total: 0}; + item = function profiled_func(...args) { + var before = performance.now(); + var result = orig_func(...args); + var delta = performance.now() - before; + var data = profile[full_name]; + data.count++; + data.total += delta; + return result; + } + } + return item; + } + }) + } + }); + } + + function dumpProfile(profile) { + let array = []; + for (let key in profile) { + if (key == "instanceNum") continue; + let data = profile[key]; + if (data.count == 0) continue; + array.push(data); + } + print(`--- Import profile for instance ${profile.instanceNum} ---`); + if (array.length == 0) return; + array.sort((a, b) => b.total - a.total); + for (let data of array) { + print(`${padl(data.name, 30)}: ${padr(data.count, 10)} ${padp(data.total, 10)}ms`); + } + } + + function padl(s, len) { + s = s.toString(); + while (s.length < len) s = s + " "; + return s; + } + function padr(s, len) { + s = s.toString(); + while (s.length < len) s = " " + s; + return s; + } + function padp(s, len) { + s = s.toString(); + var i = s.indexOf("."); + if (i == -1) i = s.length; + while (i++ < len) s = " " + s; + return s; + } + + // patch: WebAssembly.instantiate (async) + let orig_instantiate = WebAssembly.instantiate; + WebAssembly.instantiate = (m, imports, ...args) => { + let profile = {}; + let promise = orig_instantiate(m, instrument(imports, profile), ...args); + promise.then((instance) => { + instanceMap.set(instance, profile); + all_profiles.push(profile); + profile.instanceNum = instanceCounter++; + }); + return promise; + } + + // patch: new WebAssembly.Instance (sync) + let orig_new_instance = WebAssembly.Instance; + WebAssembly.Instance = new Proxy(orig_new_instance, { + construct: (target, args) => { + let profile = {}; + args[1] = instrument(args[1], profile); + let instance = new orig_new_instance(...args); + instanceMap.set(instance, profile); + all_profiles.push(profile); + profile.instanceNum = instanceCounter++; + return instance; + } + }); + + // expose: WebAssembly.dumpProfile(instance) + WebAssembly.dumpProfile = (instance) => { + let profile = instanceMap.get(instance); + if (profile === undefined) return; + dumpProfile(profile); + } + // expose: WebAssembly.clearProfile(instance) + WebAssembly.clearProfile = (instance) => { + let profile = instanceMap.get(instance); + if (profile === undefined) return; + for (let key in profile) { + if (key == "instanceNum") continue; + let data = p[key]; + data.count = 0; + data.total = 0; + } + } + // expose: WebAssembly.dumpAllProfiles() + WebAssembly.dumpAllProfiles = () => { + for (let profile of all_profiles) dumpProfile(profile); + } + // expose: WebAssembly.getProfile(instance) + // returns: { + // func_name1: {name: func_name1, count: <num>, total: <num>} + // func_name2: {name: func_name1, count: <num>, total: <num>} + // ... + // } + WebAssembly.getProfile = (instance) => { + return instanceMap.get(instance); + } +})(); |