diff options
-rw-r--r-- | src/library.js | 30 | ||||
-rw-r--r-- | system/include/emscripten.h | 13 | ||||
-rw-r--r-- | tests/runner.py | 33 |
3 files changed, 75 insertions, 1 deletions
diff --git a/src/library.js b/src/library.js index faa86c68..4d230bcc 100644 --- a/src/library.js +++ b/src/library.js @@ -5417,6 +5417,36 @@ LibraryManager.library = { EMSCRIPTEN_COMMENT__inline: function(param) { param = stripCorrections(param); return '// ' + Variables.globals[param].value.text.replace('\\00', '') + ' '; + }, + + $Profiling: { + max_: 0, + times: null, + invalid: 0, + dump: function() { + if (Profiling.invalid) { + print('Invalid # of calls to Profiling begin and end!'); + return; + } + print('Profiling data:') + for (var i = 0; i < Profiling.max_; i++) { + print('Block ' + i + ': ' + Profiling.times[i]); + } + } + }, + EMSCRIPTEN_PROFILE_INIT__deps: ['$Profiling'], + EMSCRIPTEN_PROFILE_INIT: function(max_) { + Profiling.max_ = max_; + Profiling.times = new Array(max_); + for (var i = 0; i < max_; i++) Profiling.times[i] = 0; + }, + EMSCRIPTEN_PROFILE_BEGIN__inline: function(id) { + return 'Profiling.times[' + id + '] -= Date.now();' + + 'Profiling.invalid++;' + }, + EMSCRIPTEN_PROFILE_END__inline: function(id) { + return 'Profiling.times[' + id + '] += Date.now();' + + 'Profiling.invalid--;' } }; diff --git a/system/include/emscripten.h b/system/include/emscripten.h index 4d321b2c..0ce31e9f 100644 --- a/system/include/emscripten.h +++ b/system/include/emscripten.h @@ -23,6 +23,19 @@ extern void emscripten_run_script(const char *script); */ extern void EMSCRIPTEN_COMMENT(const char *text); +/* + * Profiling tools. + * INIT must be called first, with the maximum identifier that + * will be used. BEGIN will add some code that marks + * the beginning of a section of code whose run time you + * want to measure. END will finish such a section. Note: If you + * call begin but not end, you will get invalid data! + * The profiling data will be written out if you call Profile.dump(). + */ +extern void EMSCRIPTEN_PROFILE_INIT(int max); +extern void EMSCRIPTEN_PROFILE_BEGIN(int id); +extern void EMSCRIPTEN_PROFILE_END(int id); + #ifdef __cplusplus } #endif diff --git a/tests/runner.py b/tests/runner.py index 3fd63574..fe2f0f85 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -3381,6 +3381,38 @@ if 'benchmark' not in str(sys.argv): self.do_run(src, '*hello slim world*', build_ll_hook=hook) def test_profiling(self): + src = ''' + #include <emscripten.h> + #include <unistd.h> + + int main() + { + EMSCRIPTEN_PROFILE_INIT(3); + EMSCRIPTEN_PROFILE_BEGIN(0); + usleep(10 * 1000); + EMSCRIPTEN_PROFILE_END(0); + EMSCRIPTEN_PROFILE_BEGIN(1); + usleep(50 * 1000); + EMSCRIPTEN_PROFILE_END(1); + EMSCRIPTEN_PROFILE_BEGIN(2); + usleep(250 * 1000); + EMSCRIPTEN_PROFILE_END(2); + return 0; + } + ''' + + def post1(filename): + src = open(filename, 'a') + src.write(''' + Profiling.dump(); + ''') + src.close() + + self.do_run(src, '''Profiling data: +Block 0: ''', post_build=post1) + + # Part 2: old JS version + Settings.PROFILE = 1 Settings.INVOKE_RUN = 0 @@ -3427,7 +3459,6 @@ if 'benchmark' not in str(sys.argv): ''') src.close() - # Using build_ll_hook forces a recompile, which leads to DFE being done even without opts self.do_run(src, ': __Z6inner1i (5000)\n*ok*', post_build=post) ### Integration tests |