* Enable some already-working wasm tests
* Move code in test_add_function into files for easier debugging
* Add optional note to no_wasm_backend annotation
Add notes to some tests that show up when ran, giving more information as to why a given test isn't ran with wasm_backend. Should be helpful for triage.
* Fix test_fs_direct to work in a js-engine-agnostic way
* Refactor test_i64 into four separate tests
Move the test input into files.
Remove @no_wasm_backend from two of the tests that already work
* Refactor a bunch of tests to reduce line noise
Abstract out the .in .out test pattern to reduce duplication
* Un-enable some not-working tests
* Add non-.in/.out extensions to some tests
* Refactoring + triage
* Yet more refactoring and triage
* Add test to verify nested va_copy
* Add Jacob Gravelle to AUTHORS
* Merge no_wasm_backend_note with no_wasm_backend
* Rename all .in files to .c files
Refactor all the remaining trivial tests to use do_run_in_out_file_test.
Let do_run_in_out_file_test select from a list of possible extensions, so test code only has to specify path and can ignore extension.
* Fix up test failures found from running all asm tests
* More categorization of wasm_backend test failures
* Remove unused code in system_libs.py
* Include .cc files as legal input files
* Fix v8-specific test failures
d8 doesn't support console.log, and d8 complains that writeStringToMemory is deprecated.
* Add missing canOwn parameter to FS.createDataFile calls
`undefined` was silently passed in these cases. `false` is used
everywhere to avoid functional changes, since `undefined` is falsy.
* Add Andras Kucsma to AUTHORS
* Fix inlining bug
Currently INLINING_LIMIT option does not do anything for clang. (And in
opt, emcc only checks whether it is 0 or not, so the limit number given
actually does not matter unless it is 0.)
So we give -O2, clang inlines short functions even if INLINING_LIMIT is
nonzero. This patch fixes this bug.
* Add a test
* Add Heejin Ahn to AUTHORS list
This fixes the returned string in case the version is neither "1.0" nor "3.00".
The WebGL GLSL version information is returned in the vendor-specific information field.
Currently the BINARYEN -s setting is used both as a flag to enable wasm
creation with binaryen, and to specify the path. This change keeps -s
BINARYEN=1 to enable binaryen, but moves the path to a setting called
BINARYEN_ROOT in the config file, alongside LLVM_ROOT and
EMSCRIPTEN_ROOT. It also makes the path include the 'bin' directory for
consistency with those directories.
This change adds support for duplicate function elimination (DFE) to the
JavaScript optimizer. A new JS file has been added -
eliminate-duplicate-functions.js - which is used to postprocess the
output generated by Emscripten. We add a new file, rather than
augmenting the existing JS optimizer file, for a variety of reasons -
pass independence, reduced coupling between Python scripts and the JS
optimizer, etc.
We introduce a multipass algorithm in which each pass consists of the
following four phases:
Phase 1 - identify duplicate functions using a hash of the function body
Phase 2 - identify variable names that would conflict after renaming
function calls
Phase 3 - generate mapping from equivalent functions to their
replacement function - use the information from Phase 2 to ensure that
the replacement function is not a variable name
Phase 4 - use the mapping generated in Phase 3 to perform the reduction
NOTE: In some rare cases, we may actually not be able to move on from
Phase 3 if we find that we cannot generate a mapping because of
conflicts with variable names.
One pass can reveal new sets of identical functions which in turn can be
reduced by further passes. Empirically, four or five passes are
sufficient to eliminate all duplicate functions. Internally, therefore,
the elimination will perform 5 passes by default. This can be overridden
by setting ELIMINATE_DUPLICATE_FUNCTIONS_PASSES to 1 in settings.js or
on the Emscripten command line.
Generated asm.js is broken into several batches (at function boundaries)
to enable parallelization of the elimination. This saves on memory and
makes use of more CPU cores to save on build time. A number of tests
have been introduced to test this functionality as well.
The change also introduces various tweaks to the amount of diagnostic
information that is dumped out by the JavaScript optimizer. Verbose
logging is now only enabled in debug mode (via the EMCC_LOG_DEBUG
environment variable). We also dump backtraces on encountering unhandled
exceptions: this is useful when Emscripten runs as part of a large build
process. In order to view detailed information about which functions
were merged, set the
ELIMINATE_DUPLICATE_FUNCTIONS_DUMP_EQUIVALENT_FUNCTIONS value to 1 in
settings.js or via the Emscripten command line. This generates a log
file in the same directory as the generated JavaScript listing the sets
of merged functions. This can be decoded using the symbol map generated
by Emscripten. It is, therefore, recommended that developers enable
symbol map generation when attempting to modify or debug this feature.
Since DFE increases build time significantly, it is disabled by default.
It can be enabled by setting ELIMINATE_DUPLICATE_FUNCTIONS to 1 either
in settings.js or by adding "-s ELIMINATE_DUPLICATE_FUNCTIONS=1" on the
Emscripten command line. The poppler test has been updated to also run
with the ELIMINATE_DUPLICATE_FUNCTIONS setting set to 1.
Improvements/future work
It has been observed that on average we experience a code size reduction
of 25% when transpiling large C++ code bases. Typically, C++ code that
makes heavy use of templates will experience the greatest reduction in
code size. There are several directions that future work might take:
* Deduplication of code across templates: e.g. reduction of
std::vector<long> and std::vector<int> to single instantiations of
template code when appropriate
* Histogram-based selection of candidates for replacement: improved code
size should be attainable by assigning the shortest identifiers to the
most frequently referenced functions (in the style of Huffman coding)
* Convergence: the five-pass default chosen in this implementation is
based on empirical observations on a 150,000LOC C++ code base
* Candidate selection: this will, most likely, influence both the
convergence time (i.e. number of passes) and the code size reduction;
currently, when selecting candidates, we choose the shortest identifier
from the list that is not also a variable name
DNS.lookup_name uses __inet_pton4_raw and __inet_pton6_raw to detect if
it has been given a valid address string, but if the result evaluates to
false, still attempted to generate a 172.29.0.0/16 IP address.
Instead, correctly check the return values of the __inet_pton... methods
against precisely null, as is done by the other users.
* Fxed ui to listen for proper events and to be in proper scope.
* Fixed the allocations stats to work properly and be in the correct scope.
* Fixed onFree and onMalloc to reference the right functions in the correct scope.