Skip to content

Mettle v0.16.2

Choose a tag to compare

@suidvandiewereld suidvandiewereld released this 18 Aug 07:24
· 437 commits to main since this release

Mettle v0.16.2

Programs are about eight times smaller. A release build of examples/fib was
74,752 bytes and is now 9,728. The machine code Mettle generates is unchanged,
so benchmarks and compile times are the same. Windows 931/931, Linux 917/917.

Four things were padding every binary.

Fixed

  • 33 KB of zeros were written into every image. GCC with -fdata-sections
    gives each zero-initialized static its own .data section carrying real zero
    bytes, and the runtime has several large ones. An all-zero data section with
    no relocations is now carried as .bss, which occupies no file bytes.
  • The internal linker kept every section of every input object. It now
    collects the ones nothing reachable references, following relocations out
    from the entry point and from the sections that cannot be collected.
  • Unused library functions and their string literals could not be dropped.
    Each function now gets its own section (.text$name on COFF, .text.name on
    ELF), and each string literal gets its own on COFF. A program that never
    calls print_int no longer carries it or the strings it names.
  • Switch jump tables rooted the whole printf family. GCC puts them in a
    plain .rdata section that has to be kept, and their relocations point into
    vsnprintf, vsscanf and the float formatters. The runtime is now built
    with -fno-jump-tables, worth about 9 KB in every binary.

Sizes

Release builds on Windows: fib 9,728 bytes, base64_encode 7,680,
crc32 and word_count 7,168, float_sum and binary_search 6,144.
A debug build of fib is 8,192, down from 73,216. On Linux fib is 8,840.
A --safe build of word_count is 16,384, its 64 KB of checked-access
tables having moved to .bss.

New

METTLE_LINK_GC_REPORT=1 prints every section the link kept or collected,
with its object and size, to stderr. This is what found the jump tables.

Changed

  • --emit-obj objects carry one section per function, so anything that
    reads them with an external linker or an object tool sees the new names.
    Linux links already pass --gc-sections and collect them.
  • An undefined external that nothing reachable references is no longer
    recorded.
    A program that declares an extern it never calls does not import
    it.
  • Building Mettle from source now compiles the runtime with -fno-jump-tables.

Full Changelog: v0.16.1...v0.16.2

Full Changelog: v0.16.1...v0.16.2