Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Omit some C++ subsystems

I notice that with emscripten, even relatively small C++ files can quickly be turned into rather huge JavaScript files. Example:

#include <memory>
int main(int argc, char** argv) {
  std::shared_ptr<int> sp(new int);
}

Compile this with a recent emsdk using a command like

em++ -std=c++11 -s DISABLE_EXCEPTION_CATCHING=1 -s NO_FILESYSTEM=1 \
     -s NO_BROWSER=1 -s NO_EXIT_RUNTIME=1 -O3 -o foo.js foo.cc

The resulting file is over 400k big. With -g thrown in I can do

grep -n '^function _' foo.js | c++filt -_

and see what kinds of functions we have there. Here are some examples:

std::__1::moneypunct<char, false>::do_thousands_sep() const
std::__1::locale::~locale()
std::__1::basic_string<wchar_t, …>::~basic_string()
std::__1::time_get<…>::__get_day(…) const
std::__1::codecvt<wchar_t, char, __mbstate_t>::codecvt(unsigned int)
std::__1::locale::__imp::install(std::__1::locale::facet*, long)
_printf_core

I'm not calling any of this myself, but nevertheless the functions all get included. Probably many of them are included in some virtual function table. The others might be due to some static initializer.

If this were normal code linked against a single shared library somewhere on my HDD; I wouldn't object. But half a megabyte in JavaScript code to be transferred, just for a single shared pointer? There has to be a way to avoid that.

like image 843
MvG Avatar asked Apr 04 '15 22:04

MvG


1 Answers

One solution, implemented here, is simply splitting the C++ library in several parts. By moving the code dealing with I/O and locale into a separate library, all the code which can work without this can avoid the static initializer of the I/O subsystem which leads to a dependency on the functions described above. Unfortunately this will also affect strstream, for obvious reasons.


Update: Since upstream commit 301e4ad (first included in release 1.30.6), the system libraries are no longer compiled as a single *.bc file, but instead as a *.a static library which contains several distinct objects. Of these, only the required ones actually get linked in, which reduces code size for simple cases quite a lot.

like image 104
MvG Avatar answered Sep 24 '22 01:09

MvG