Bug 74803 Comment 99 Edit History

Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.

Some extra bits on that topic: if we're interested in decreasing the number of global constructor called at startup, the following recipe proves to be quite helpful:

```
# 1. make sure to deactivate unified build, as it makes tracking more difficult
./mach configure --disable-unified-build

# 2. compile fx
./mach build

# 3. count global constructors (assuming linux x86_64)
 nm obj-x86_64-pc-linux-gnu/dist/bin/libxul.so  | grep -c _GLOBAL__sub_

# 4. this loop gathers the actual assembly code of each initialization, which make it easier to track origin
nm obj-x86_64-pc-linux-gnu/dist/bin/libxul.so  | grep  _GLOBAL__sub_ | while read line ; do addr=`echo $line | cut -d ' ' -f1`; echo "###### $line ######" ; gdb --batch -ex 'file obj-x86_64-pc-linux-gnu/dist/bin/libxul.so' -ex "disass 0x$addr" | c++filt ; done | tee global-symbols.log

# 5. explore global-symbols.log
```

Some notes:

- the perfherder metric counts constructors on unified build, so constructors are aggregated
- `-Wglobal-constructors` works at a syntax level. the compiler is often capable of optimizing those away, which is why we rely on the above
- `constinit` would help a lot here, but it's C++20
-  the `frozen` library would help in some cases, but it's an extra 3rd party library
- `constexpr` is quite often the way to go.
- local static variables are not stored as global constructors, but there access is always protected by a thread-safe guard, so there's a runtime cost
Some extra bits on that topic: if we're interested in decreasing the number of global constructor called at startup, the following recipe proves to be quite helpful:

```
# 1. make sure to deactivate unified build, as it makes tracking more difficult
./mach configure --disable-unified-build

# 2. compile fx
./mach build

# 3. count global constructors (assuming linux x86_64)
 nm obj-x86_64-pc-linux-gnu/dist/bin/libxul.so  | grep -c _GLOBAL__sub_

# 4. this loop gathers the actual assembly code of each initialization, which make it easier to track origin
nm obj-x86_64-pc-linux-gnu/dist/bin/libxul.so  | grep  _GLOBAL__sub_ | while read line ; do addr=`echo $line | cut -d ' ' -f1`; echo "###### $line ######" ; gdb --batch -ex 'file obj-x86_64-pc-linux-gnu/dist/bin/libxul.so' -ex "disass 0x$addr" | c++filt ; done | tee global-symbols.log

# 5. explore global-symbols.log
```

Some notes:

- the perfherder metric counts constructors on unified build, so constructors are aggregated
- `-Wglobal-constructors` works at a syntax level. the compiler is often capable of optimizing those away, which is why we rely on the above
- `constinit` would help a lot here, but it's C++20
-  the `frozen` library would help in some cases, but it's an extra 3rd party library
- `constexpr` is quite often the way to go.
- local static variables are not stored as global constructors, but there access is always protected by a thread-safe guard, so there's a runtime cost
- turning data structures into POD also help
- not including `<iostream>` prevents a global constructor (the one used to initialize `cout` / `cerr`). `<istream>` and `<ostream>` exist and including both doesn't add any global constructor.

Back to Bug 74803 Comment 99