# Xo 0.20 release notes


## Introduction

Xo 0.20 adds Xo's own x86-64 backend, brings native code within about
10% of LLVM's instructions, makes TLS and HTTP much faster, and gives
debuggers DWARF variables and types. See
[Correct first, fast later](/blog/correct-first-fast-later/) for how
the backends caught up. In the source, the compiler moved from
`selfhost/` to `compiler/`, and the licenses are MIT, with MIT-0 for
the standard library.

## Changes to the language

- A discarded result of a pure call is an error, `XO0209`
  ([decision 0258](https://github.com/xo-lang/xo/blob/main/knowledgebase/decisions/0258-discarded-pure-results.md)).
- A native fault inside deferred code is handled as the spec says
  (section 5.6).

## Tools

- Debugging: DWARF variables and types (Str, List, Map, enums) on the
  arm64 and LLVM backends, constant locations, and gdb and lldb
  backtraces that end cleanly
  ([decision 0252](https://github.com/xo-lang/xo/blob/main/knowledgebase/decisions/0252-dwarf-variables.md)).
  `xo debug`, a debugger written in Xo, has its reader, unwinder, batch
  session and JSON protocol working on recorded threads
  ([decision 0253](https://github.com/xo-lang/xo/blob/main/knowledgebase/decisions/0253-xo-debugger.md)).

## Runtime

- Memory copies use SIMD, atomics use LSE on Linux arm64, and task
  spawn is faster (on Linux, below tokio's current_thread).
- Reads and writes over 2 GiB work.
- Small maps have no hash table.
- Fewer reference count operations: immortal values are not counted,
  and retain and release pairs cancel.

## Compiler

- x86-64 backend
  ([decision 0254](https://github.com/xo-lang/xo/blob/main/knowledgebase/decisions/0254-amd64-backend.md)):
  `xo build --backend=amd64` builds linux/amd64 programs with no C
  toolchain, with Xo's own assembler and linker, and uses AES-NI,
  PCLMULQDQ and SHA-NI. Its geometric mean went from 1.63 to 1.14 times
  LLVM's instructions.
- arm64: the geometric mean went from 1.32 to about 1.09 times LLVM's,
  and P-256 is at parity. Load and store pairing now works on Linux,
  along with reload reuse, address and rotate folding, inline string
  pushes, constant hoisting in loops that call, loop invariant fields
  ([decision 0257](https://github.com/xo-lang/xo/blob/main/knowledgebase/decisions/0257-loop-invariant-list-fields.md)),
  and inlining of closures, map lookups, and callees with landing pads
  at closure sites
  ([decision 0256](https://github.com/xo-lang/xo/blob/main/knowledgebase/decisions/0256-inline-landing-pads.md)).

## Standard library

- TLS keep-alive requests take 19 to 27% fewer instructions (no copy of
  the connection state per read and write), plain HTTP/1.1 about 10%
  fewer, and ML-KEM 60% fewer.

## Ports

- WebAssembly: file handles and file operations over WASI, and time
  zones when a program uses them; 169 test programs pass.

## Known issues

- On Intel Macs with the LLVM backend, this version's standard library
  does not catch faults (a stale register in the unwinder's frame
  cache). Fixed in 0.21.

