StarlingMonkey icon indicating copy to clipboard operation
StarlingMonkey copied to clipboard

Running `meta-dce` build step

Open andreiltd opened this issue 8 months ago • 4 comments

I was recently looking into ways to reduce the size of the StarlingMonkey image, which currently sits at around 11MB. One of the interesting tools that we could perhaps use is wasm-metadce.

tl;dr: wasm-metadce takes a JSON file that describes the module tree and performs dead code elimination on the entire graph of both the wasm and the outside code. For example, I would imagine something like this for StarlingMonkey:

[
  {
    "name": "outside",
    "reaches": [
      "wasi-cli",
      "wasi-http",
      "wizer-resume",
      "cabi-realloc",
      "export-memory"
    ],
    "root": true
  },
  {
    "name": "wasi-cli",
    "export": "wasi:cli/[email protected]#run"
  },
  {
    "name": "wasi-http",
    "export": "wasi:http/[email protected]#handle"
  },
  {
    "name": "wizer-resume",
    "export": "wizer.resume"
  },
  {
    "name": "cabi-realloc",
    "export": "cabi_realloc"
  },
  {
    "name": "export-memory",
    "export": "memory"
  }
]

In fact I tried to integrate this tool to our build system and this is what it was able to DCE:

unused: func$JS::Realm::resetRandomNumberGenerator\28\29
unused: func$__env_rm_add
unused: func$__wasilibc_deinitialize_environ
unused: func$__wizer_initialize\28\29
unused: func$_initialize
unused: func$api::Engine::finish_pre_initialization\28\29
unused: func$clearenv
unused: func$js::ResetMathRandomSeed\28JSContext*\29
unused: func$std::__2::basic_istream<char\2c\20std::__2::char_traits<char>>&\20std::__2::getline\5babi:v160000\5d<char\2c\20std::__2::char_traits<char>\2c\20std::__2::allocator<char>>\28std::__2::basic_istream<char\2c\20std::__2::char_traits<char>>&\2c\20std::__2::basic_string<char\2c\20std::__2::char_traits<char>\2c\20std::__2::allocator<char>>&\29
unused: func$std::__2::basic_istream<char\2c\20std::__2::char_traits<char>>&\20std::__2::getline\5babi:v160000\5d<char\2c\20std::__2::char_traits<char>\2c\20std::__2::allocator<char>>\28std::__2::basic_istream<char\2c\20std::__2::char_traits<char>>&\2c\20std::__2::basic_string<char\2c\20std::__2::char_traits<char>\2c\20std::__2::allocator<char>>&\2c\20char\29
unused: func$std::__2::basic_istream<char\2c\20std::__2::char_traits<char>>::sentry::operator\20bool\5babi:v160000\5d\28\29\20const
unused: func$std::__2::basic_istream<char\2c\20std::__2::char_traits<char>>::sentry::sentry\28std::__2::basic_istream<char\2c\20std::__2::char_traits<char>>&\2c\20bool\29
unused: func$std::__2::char_traits<char>::eq\28char\2c\20char\29
unused: func$std::__2::istreambuf_iterator<char\2c\20std::__2::char_traits<char>>::istreambuf_iterator\5babi:v160000\5d\28\29
unused: func$std::__2::istreambuf_iterator<char\2c\20std::__2::char_traits<char>>::istreambuf_iterator\5babi:v160000\5d\28std::__2::basic_istream<char\2c\20std::__2::char_traits<char>>&\29
unused: func$wizen\28\29

It looks like it only removed the dependencies related to wizer initialization. I guess my question is: are there anything specific that might be preventing wasm-metadce from identifying additional dead code and make the dependency analysis overly conservative?

andreiltd avatar Jun 19 '25 19:06 andreiltd

interesting.... I'm going to try this over the weekend.....

squillace avatar Jun 19 '25 20:06 squillace

@tschneidereit how do we feel about this? BTW, @andreiltd what was the resulting size reduction here?

squillace avatar Jun 20 '25 14:06 squillace

Size reduction for the graph as above is marginal which is a bit surprising. I would assume it should DCE much more than this.

andreiltd avatar Jun 23 '25 07:06 andreiltd

Nice, thank you for looking into this! ❤

I think what might be going on here is that everything inside SpiderMonkey is seen as reachable by the DCE pass. It's possible that SpiderMonkey is compiled in such a way that all functions visible to the linker are added to function tables, meaning they could in theory be called dynamically, and can't be considered dead.

There might be a way to change the build config for SpiderMonkey to make this go away, but I have no idea what that'd look like. It'd be fantastic to figure out though, because it might shrink our build pretty substantially even without the DCE pass: the linker should in theory just omit including these functions.

tschneidereit avatar Jun 23 '25 12:06 tschneidereit