Hi Internals,

Currently PHP JIT only supports x86 and x86_64 CPUs on POSIX platforms and 
Windows.[1] With the prevalence of PHP language and the notable
growth of ARM-based servers market, we believe JIT/arm64 would be in urgent 
need in the near future.

As an initial effort to enable PHP JIT/arm64, we (ARM) have supported the basic 
functionality, and (partially) implemented the compilation for
several opcodes. Currently a number of simple JIT test cases from PHP test 
framework can be passed on ARM-based machine. There are still a lot
of missing parts, such as hot loops, class/object/array operations, exception 
handling, etc, and we will continue working on them.

We would like to share our work with you (See the draft patch 
https://github.com/shqking/php-src/commit/6aaf935).
Any feedback would be greatly appreciated, and please let we know if anyone 
wants to contribute to this port.

Thanks,
Hao SUN
Email: hao....@arm.com<mailto:hao....@arm.com>

-------------------------------------------------------
Main updates:
1. JIT backend for AArch64
A new alternative, i.e. AArch64, was added while building PHP JIT. See the 
updates in the following files. Note that we adopt capstone[2] for
disassembly on AArch64.

  build/Makefile.global
  ext/opcache/config.m4
  ext/opcache/config.w32
  ext/opcache/jit/Makefile.frag
  ext/opcache/jit/zend_jit.c
  ext/opcache/jit/zend_jit_vm_helpers.c
  ext/opcache/jit/zend_jit_disasm_arm64.c
  ext/opcache/jit/zend_jit_gdb.c
  ext/opcache/jit/zend_jit_perf_dump.c

2. DynASM library
PHP JIT uses DynASM[3] (developed for LuaJIT project) to generate native code 
on the fly. We added two useful but missing features, global label
reference and dynamic register names, into DynASM/arm64. See the updates in 
files:

  ext/opcache/jit/dynasm/dasm_arm64.h
  ext/opcache/jit/dynasm/dasm_arm64.lua

Note that these two features are available on DynASM/x86.

3. compilation for opcodes on AArch64
Our main work falls in the following files.

  ext/opcache/jit/zend_jit_arm64.h
  ext/opcache/jit/zend_jit_arm64.dasc
  ext/opcache/jit/zend_jit_internal.h
  Zend/zend_vm_opcodes.h

* AArch64 registers and calling conventions are defined.

* Instruction cache must be flushed for the JIT-ed code on AArch64. See macro 
JIT_CACHE_FLUSH in file 'zend_jit_internal.h'.

* We have (partially) implemented the compilation for several opcodes, mainly 
for the function-based JIT (with opcache.jit=1203). Currently,
test cases involving internal function call (e.g. var_dump), additions with 
integers/floating-point numbers, integer overflows and simple
exception, can be supported now. See our newly added test cases under directory 
'ext/opcache/tests/jit/arm64/'.

* Trace counter stubs are implemented for tracing JIT (with
opcache.jit=1255). See zend_jit_hybrid_trace_counter_stub() and 
zend_jit_hybrid_hot_trace_stub() in file 'zend_jit_arm64.dasc'. Hot
functions can be recognized and compiled successfully. See the test case 
'hot_func_002.phpt'.

How to build and test:
Our local test environment is an ARM-based server with Ubuntu 20.04 and GCC-10. 
We follow the building commands as shown in the readme file [4].
Note that library capstone should be installed in advance.

We suggest running the JIT test cases using the following command. In our local 
test, 59 out of all 128 cases can be passed currently.
  $ make test TESTS='-d opcache.jit=1203 ext/opcache/tests/jit/'

[1] https://wiki.php.net/rfc/jit
[2] https://www.capstone-engine.org/
[3] https://luajit.org/dynasm.html
[4] https://github.com/php/php-src

Reply via email to