lisachenko / z-engine

:zap: PHP Engine Direct API
MIT License
448 stars 22 forks source link

Enable FFI+Opcache preload optimization #8

Closed lisachenko closed 4 years ago

lisachenko commented 4 years ago

Loading/parsing definition of C headers in runtime is not good, also, ffi.enable is equal to preload by default, thus, to make this library active by default, preloading of C headers should be added.

Ideally, this requires some infrastructure support to activate FFI preloading.

lisachenko commented 4 years ago

Preloading suffers from cyclic dependencies and could not preload classes that depend on each other. Let's say that class A contains a property with type B, which is initialized in constructor. Class B accepts link to the class A (aka parent instance) and stores it in his private typed property. Classes A and B are stored in different files.

In this case preload will fail...

lisachenko commented 4 years ago

There is a bug in preload + pointer casting that results in memory heap corruption: https://bugs.php.net/bug.php?id=78761

lisachenko commented 4 years ago

To make preloading work, all FFI calls should be only within the Core class, it will be preloaded by PHP, otherwise calls to FFI are restricted by the ffi.enable option.

lisachenko commented 4 years ago

Preload mode will only work in following releases of PHP7.4 (RC5 doesn't contain a patch for https://bugs.php.net/bug.php?id=78761)

lisachenko commented 4 years ago

Opcache preloading is broken, need at least PHP7.4.2 to include a bug fix for https://bugs.php.net/bug.php?id=78918

lisachenko commented 4 years ago

Windows doesn't support opcache preloading as of 7.4.2. Support was removed by @nikic in https://github.com/php/php-src/commit/59c3ddab13b5cc38e9406538801be8e134626793 due to ASLR restrictions for internal classes.

Additional details can be found here: https://github.com/php/php-src/pull/4999

nikic commented 4 years ago

Note that you can use ffi.preload instead. It works on Windows.

lisachenko commented 4 years ago

Note that you can use ffi.preload instead. It works on Windows.

Thank you for replying, Nikita! I know about this configuration option, but my header file contains some macros which should be resolved in runtime accordind to platfrom, for example ZEND_FASTCALL, thus ffi.preload can't be used for this library.