Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion tests/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
emconfigure = shared.bat_suffix(path_from_root('emconfigure'))
emconfig = shared.bat_suffix(path_from_root('em-config'))
emsize = shared.bat_suffix(path_from_root('emsize'))
emprofile = shared.bat_suffix(path_from_root('tools', 'emprofile'))
wasm_dis = os.path.join(building.get_binaryen_bin(), 'wasm-dis')
wasm_opt = os.path.join(building.get_binaryen_bin(), 'wasm-opt')

Expand Down Expand Up @@ -7374,10 +7375,20 @@ def test_closure_externs(self):
self.run_process([EMCC, path_from_root('tests', 'hello_world.c'), '--closure', '1', '--pre-js', path_from_root('tests', 'test_closure_externs_pre_js.js'), '--closure-args', '--externs "' + path_from_root('tests', 'test_closure_externs.js') + '"'])

def test_toolchain_profiler(self):
# Verify some basic functionality of EM_PROFILE_TOOLCHAIN
environ = os.environ.copy()
environ['EM_PROFILE_TOOLCHAIN'] = '1'
# replaced subprocess functions should not cause errors

self.run_process([emprofile, '--reset'])
err = self.expect_fail([emprofile, '--graph'])
self.assertContained('No profiler logs were found', err)

self.run_process([EMCC, path_from_root('tests', 'hello_world.c')], env=environ)
self.assertEqual('hello, world!', self.run_js('a.out.js').strip())

self.run_process([emprofile, '--graph'])
self.assertTrue(glob.glob('toolchain_profiler.results*.html'))
self.assertTrue(glob.glob('toolchain_profiler.results*.json'))

def test_noderawfs(self):
fopen_write = open(path_from_root('tests', 'asmfs', 'fopen_write.cpp')).read()
Expand Down
1 change: 1 addition & 0 deletions tools/create_entry_points.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
emscons
emsize
tools/emdump
tools/emprofile
tools/file_packager
'''.split()

Expand Down
29 changes: 29 additions & 0 deletions tools/emprofile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/sh
# Copyright 2020 The Emscripten Authors. All rights reserved.
# Emscripten is available under two separate licenses, the MIT license and the
# University of Illinois/NCSA Open Source License. Both these licenses can be
# found in the LICENSE file.
#
# Entry point for running python scripts on UNIX systems.
#
# To modify this file, edit `tools/run_python.sh` and then run
# `tools/create_entry_points.py`

if [ -z "$PYTHON" ]; then
PYTHON=$EMSDK_PYTHON
fi

if [ -z "$PYTHON" ]; then
PYTHON=$(which python3 2> /dev/null)
fi

if [ -z "$PYTHON" ]; then
PYTHON=$(which python 2> /dev/null)
fi

if [ -z "$PYTHON" ]; then
echo 'unable to find python in $PATH'
exit 1
fi

exec "$PYTHON" "$0.py" "$@"
13 changes: 11 additions & 2 deletions tools/emprofile.bat
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
@echo off
python "%~dp0\emprofile.py" %*
:: Entry point for running python scripts on windows systems.
:: To modify this file, edit `tools/run_python.bat` and then run
:: `tools/create_entry_points.py`

@setlocal
@set EM_PY=%EMSDK_PYTHON%
@if "%EM_PY%"=="" (
set EM_PY=python
)

@"%EM_PY%" "%~dp0\%~n0.py" %*
67 changes: 35 additions & 32 deletions tools/emprofile.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# Copyright 2016 The Emscripten Authors. All rights reserved.
# Emscripten is available under two separate licenses, the MIT license and the
# University of Illinois/NCSA Open Source License. Both these licenses can be
Expand All @@ -16,34 +16,24 @@
# If set to 1, always generates the output file under the same filename and doesn't delete the temp data.
DEBUG_EMPROFILE_PY = 0

OUTFILE = 'toolchain_profiler.results_' + time.strftime('%Y%m%d_%H%M')
for arg in sys.argv:
if arg.startswith('--outfile='):
OUTFILE = arg.split('=', 1)[1].strip().replace('.html', '')


# Deletes all previously captured log files to make room for a new clean run.
def delete_profiler_logs():
try:
if os.path.exists(profiler_logs_path):
shutil.rmtree(profiler_logs_path)
except IOError:
pass


def list_files_in_directory(d):
files = []
try:
items = os.listdir(d)
for i in items:
if os.path.exists(d):
for i in os.listdir(d):
f = os.path.join(d, i)
if os.path.isfile(f):
files += [f]
return files
except IOError:
return []
files.append(f)
return files


def create_profiling_graph():
def create_profiling_graph(outfile):
log_files = [f for f in list_files_in_directory(profiler_logs_path) if 'toolchain_profiler.pid_' in f]

all_results = []
Expand All @@ -63,26 +53,30 @@ def create_profiling_graph():
print('Failed to parse JSON file "' + f + '"!', file=sys.stderr)
sys.exit(1)
if len(all_results) == 0:
print('No profiler logs were found in path "' + profiler_logs_path + '". Try setting the environment variable EM_PROFILE_TOOLCHAIN=1 and run some emcc commands, and then rerun "python emprofile.py --graph" again.')
return
print(f'No profiler logs were found in path: ${profiler_logs_path}.\nTry setting the environment variable EM_PROFILE_TOOLCHAIN=1 and run some emcc commands, then re-run "emprofile.py --graph".', file=sys.stderr)
return 1

all_results.sort(key=lambda x: x['time'])

json_file = OUTFILE + '.json'
json_file = outfile + '.json'
open(json_file, 'w').write(json.dumps(all_results, indent=2))
print('Wrote "' + json_file + '"')

html_file = OUTFILE + '.html'
html_file = outfile + '.html'
html_contents = open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'toolchain_profiler.results_template.html'), 'r').read().replace('{{{results_log_file}}}', '"' + json_file + '"')
open(html_file, 'w').write(html_contents)
print('Wrote "' + html_file + '"')

if not DEBUG_EMPROFILE_PY:
delete_profiler_logs()

return 0


if len(sys.argv) < 2:
print('''Usage:
def main(args):
if len(args) < 2:
print('''\
Usage:
emprofile.py --reset
Deletes all previously recorded profiling log files.

Expand All @@ -93,14 +87,23 @@ def create_profiling_graph():

--outfile=x.html
Specifies the name of the results file to generate.
''')
sys.exit(1)
''')
return 1

if '--reset' in args:
delete_profiler_logs()
elif '--graph' in args:
outfile = 'toolchain_profiler.results_' + time.strftime('%Y%m%d_%H%M')
for arg in args:
if arg.startswith('--outfile='):
outfile = arg.split('=', 1)[1].strip().replace('.html', '')
return create_profiling_graph(outfile)
else:
print('Unknown command "' + args[1] + '"!')
return 1

return 0


if '--reset' in sys.argv:
delete_profiler_logs()
elif '--graph' in sys.argv:
create_profiling_graph()
else:
print('Unknown command "' + sys.argv[1] + '"!')
sys.exit(1)
if __name__ == '__main__':
sys.exit(main(sys.argv))