Two big changes were cited as part of the new format:
- There is no longer a separate linked encoding for execution. This means bytecode can no longer be direct threaded, since the address of the instruction could not be stored to disk, as it changes with each program invocation.
- To make the single format suitable for both storage and execution, instructions can be encoded as narrow or wide. With a narrow instruction, the opcode and operands each take one byte. A wide instruction consists of a special single-byte opcode,
op_wide, followed by a series of four-byte slots for the original opcode and its arguments.
The new bytecode also features a metadata table. When linking, a side table is initialized with all writeable data associated with a given instruction. In addition, type safety was increased through improvements to bytecode-related infrastructure. A caching API for the new bytecode is in development in the WebKit repo. Developers can contribute at bugs.webkit.org.
Developers involved with the project had sought to fix two major issues with the old bytecode format. First, it used too much memory, and second, it included an instruction stream that was writeable, which prevented memory-mapping the bytecode stream. The old bytecode format also had optimizations that were no longer beneficial, such as direct-threading.
The new bytecode format is available on the Safari 12.1 browser, which shipped with iOS 12.1 and MacOS 10.14.4, and the Safari Technology Preview. You can download the Safari Technology Preview from webkit.org.