xref: /PHP-8.4/ext/opcache/jit/README.md (revision be275433)
1Opcache JIT
2===========
3
4This is the implementation of Opcache's JIT (Just-In-Time compiler),
5This converts the PHP Virtual Machine's opcodes into Intermediate
6Representation and uses [IR - Lightweight JIT Compilation Framework](https://github.com/dstogov/ir)
7to produce optimized native code. The necessary part of the IR
8Framework is embedded into php-src.
9
10Running tests of the JIT
11------------------------
12
13Then, to test the JIT, e.g. with opcache.jit=tracing, an example command
14based on what is used to test in CI:
15
16```
17make test TESTS="-d opcache.jit_buffer_size=16M -d opcache.enable=1 -d opcache.enable_cli=1 -d opcache.protect_memory=1 -d opcache.jit=tracing --repeat 2 --show-diff -j$(nproc) ext/opcache Zend"
18```
19
20- `opcache.jit_buffer_size=16M` enables the JIT in tests by providing 16 megabytes of
21  memory to use with the JIT to test with.
22- `opcache.protect_memory=1` will detect writing to memory that is meant to be
23  read-only, which is sometimes the cause of opcache bugs.
24- `--repeat 2` is optional, but used in CI since some JIT bugs only show up after processing a
25  request multiple times (the first request compiles the trace and the second executes it)
26- `-j$(nproc)` runs as many workers to run tests as there are CPUs.
27- `ext/opcache/` and `Zend` are the folders with the tests to run, in this case opcache
28  and the Zend engine itself.  If no folders are provided, all tests are run.
29
30When investigating test failures such as segmentation faults,
31configuring the build of php with `--enable-address-sanitizer` to enable
32[AddressSanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer) is often useful.
33
34Some of the time, adding `-m --show-mem` to the `TESTS` configuration is also useful to test with [valgrind](https://valgrind.org/) to detect out of bounds memory accesses.
35Using valgrind is slower at detecting invalid memory read/writes than AddressSanitizer when running large numbers of tests, but does not require rebuilding php.
36
37Note that the JIT supports 3 different architectures: `X86_64`, `i386`, and `arm64`.
38
39Miscellaneous
40-------------
41
42### How to build 32-bit builds on x86_64 environments
43
44Refer to [../../../.github/workflows/push.yml](../../../.github/workflows/push.yml) for examples of
45dependencies to install.
46
47If you are running this natively (outside of Docker or a VM):
48
49- Consider running in docker/a VM instead if you are unfamiliar with this.
50- Avoid purging packages.
51- Avoid `-y` - if the package manager warns you that the dependencies conflict
52  then **don't** try to force install them.
53
54#### Prerequisites for 32-bit builds
55
56This assumes you are using a Debian-based Linux distribution and have already
57set up prerequisites for regular development.
58
59```
60sudo dpkg --add-architecture i386
61sudo apt-get update -y
62# As well as anything else from .github/actions/apt-x32/action.yml that you're testing locally
63sudo apt-get install \
64    gcc-multilib g++-multilib \
65    libxml2-dev:i386 \
66    libc6:i386
67```
68
69#### Compiling 32-bit builds
70
71This assumes you are using a Debian-based Linux distribution and have already
72set up prerequisites for 32-bit development.
73
74```
75export LDFLAGS=-L/usr/lib/i386-linux-gnu
76export CFLAGS='-m32'
77export CXXFLAGS='-m32'
78export PKG_CONFIG=/usr/bin/i686-linux-gnu-pkg-config
79./configure --disable-all --enable-opcache --build=i686-pc-linux-gnu
80make -j$(nproc)
81```
82
83#### Running tests of the JIT on 32-bit builds
84
85See the section "Running tests of the JIT".
86
87### Testing the jit with arm64 on x86 computers
88
89https://www.docker.com/blog/faster-multi-platform-builds-dockerfile-cross-compilation-guide/
90may be useful for local development.
91
92Note that this is slower than compiling and testing natively.
93
94```
95# After following steps in https://www.docker.com/blog/faster-multi-platform-builds-dockerfile-cross-compilation-guide/
96cp .gitignore .dockerignore
97echo .git >> .dockerignore
98
99docker build --network=host -t php-src-arm64-example -f ext/opcache/jit/Dockerfile.arm64.example .
100docker run -it --rm php-src-arm64-example
101```
102
103Then, the docker image can be used to run tests with `make test`.
104For example, to test `ext/opcache` in parallel with the tracing JIT enabled:
105
106```
107docker run -it php-src-arms-example make test TESTS="-d opcache.jit_buffer_size=16M -d opcache.enable=1 -d opcache.enable_cli=1 -d opcache.protect_memory=1 -d opcache.jit=tracing --repeat 2 --show-diff -j$(nproc) ext/opcache"
108```
109