Commit Graph

341 Commits

Author SHA1 Message Date
Ilija Tovilo
631bc81607
Implement stackless internal function calls
Co-authored-by: Dmitry Stogov <dmitry@zend.com>

Closes GH-12461
2024-02-06 17:42:28 +01:00
Ilija Tovilo
ffc250d245
Add runtime type inference verification
Co-authored-by: Dmitry Stogov <dmitry@zend.com>

Closes GH-12930
2024-01-19 09:29:14 +01:00
Dmitry Stogov
8cc6b3576e
Fixed GH-12596: Segmentation fault on AArch64 release build with opcache.jit=1112 (#12813) 2023-12-05 12:04:00 +03:00
Ilija Tovilo
964e9d806b
Split complex regexes to multiple lines in zend_vm_gen.php
As requested by Dmitry in GH-12461 for easier reviewing.
2023-10-27 18:10:48 +02:00
Dmitry Stogov
caf102dfae
A new PHP JIT implementation based on IR JIT framework (#12079)
* IR update

* Use folding to allow constant folding and common subexpression elimination

* Implement IR JIT for INIT_FCALL, INIT_FCALL_BY_NAME and INIT_NS_FCALL_BY_NAME

* Implement IR JIT for SEND_VAL and SEND_VAL_EX

* Implement IR JIT for SEND_REF

* Implement IR JIT for SEND_VAR* instructions (incompltere - few tests failures)

* Implement IR JIT for CHECK_FUNC_ARG

* Implement IR JIT for CHECK_UNDEF_ARGS

* Implement IR JIT for ROPE_INIT, ROPE_ADD and ROPE_END

* Implement IR JIT for FREE, FE_FREE, ECHO, STRLEN and COUNT

* Implement IR JIT for IN_ARRAY

* Implement IR JIT support for separate VM stack overflow check

* Implement IR JIT for INIT_DYNAMIC_CALL

* Implemenr IR JIT for INIT_METHOD_CALL

* Fix IR JIT for IN_ARRAY and COUNT

* Implement IR JIT for VERIFY_RETURN_TYPE

* Force C compiler to store preserved registers to allow JIT using them

* Implement IR JIT for DO_FCALL, DO_UCALL, DO_ICALL and DO_FCALL_BY_NAME

* Implement IR JIT for FETCH_CONSTANT

* Fix (reverse) guard conditions

* Implement IR JIT for RECV and RECV_INIT

* Implement IR JIT for RETURN

* Implement IR JIT for BIND_GLOBAL

* Fix guard for: int++ => double

* Fix exception handling

* Allow deoptimization of zval type only (if some register is spilled by the IR engine)

* Fix overflow handling

* Implement IR JIT for FE_RESET_R and FE_FETCH_R

* Eliminate extra temporary register

* Better registers usage

* Implement IR JIT for FETCH_DIM_* and ISSET_DIM

* Implement IR JIT for ASSIGN_DIM and ASSIGN_DIM_OP

* cleanup

* Generae IR that produces a better x86[_64] code

* Allow trace register allocation for live ranges terminated before entering a called function

* Remove following END->BEGIN nodes during IR construction

* Remove useless (duplicate) guard

* Avoid useless exception check

* Prevent duplicate store

* Eliminate repatable re-assignment of stack zval types

* Enable combination of some instructions with the following SEND_VAL for IR JIT

* Avoid generation of useless RLOADs

* Eliminatare refcouting in a sequence of FETCH_DIM_R

* Fix assertion

* Remove ZREG_ZVAL_ADDREF flag from an element of abstract stack

* Implement IR JIT for FETCH_OBJ_*

* Implement IR JIT for ASSIGN_OBJ

* Implement IR JIT for ASSIGN_OBJ_OP

* cleanup

* Implement IR JIT for (PRE/POST)_(INC/DEC)_OBJ

* ws

* cleanup

* Fix IR JIT for constructor call

* Fix opcache.jit=1201 IR JIT.

With opcache.jit=1201  we still have to generate code for follow and target basic blocks with single exiting VM instruction. We mat just omit the entry point.

* Fix IR construction for the case when both IF targets are the same

* Avoid PHP LEAVE code duplication in function IR JIT.

* Reload operands from memeory when overflow (this improves hot code)

* Implement IR JIT for SWITCH_LONG, SWITCH_STRING and MATCH

* Initialize result to IS_UNDEF

* Fix JIT integraion with observer (Zend/tests/gh10346.phpt failure)

* Fix incorrect compilation of FE_FETCH with predicted empty array

* Fix register allocation

* Use sign extension inxted of zero

* Fix trace register allocator

* cleanp

* Fix address sanitizer warning

* Calculate JIT trace prologue sixe on startup (to avoid magic constants).

* Add cgecks for merge arrays overflow (this should be refactored using lists)

* Cache TLS access to perform corresponding read once per basic block

* cleanup unused variable

* Fix IR JIT support for CLANG build (CALL VM without global register variables)

* Fix IR JIT for CALL VM with global register variables

* Allow %rpb ysage in JIT for CALL VM (we save and restore it in prologue/epilogue anyway)

* cleanup

* Allocate enough fixed stack to keep preserved registers

* We don't have to care about x29 and x30

* cleanup (JMPZ/NZ_EX work fine)

* Revert "cleanup (JMPZ/NZ_EX work fine)"

This reverts commit cf8dd74a040e225d290d8ac4f5e33df638e6f8b8.

* Don't allocate register for PHP variables that are loaded from memory and used once

* Eliminate redundand deoptimization stores

* cleanup

* cleanup

* cleanup

* Optimization for constant comparison

* Cleanup and elimination of dead deoptimization stores

* Eliminate duplicate constant loading

* Set proper initial SP offset info for GDB backtraces

This doesn't take into account the following SP/FP modifications

* Add spill stores

* Remove low limit on number of deoptimization constants

* Emit dead code only when it's really necessary for IR graph

* cleanup

* cleanup

* Prefer loading long constants from memory (instead of loading immediate value)

* Regiter disasm labels using macros (add missing helpers)

* Make IR franework to care about GUARD JMP reordering

* Avoid reloading

* Improve register allocation for IR tracing JIT

* Add comment

* Fix deoptimization on result type guard of FETCH_DIM_R and FETCH_OBJ_R

* If HYBRID VM can't provide some stack space for JIT code in "red zone" then JIT has to reserve stack space itself

* Dump IR for stubs only if disassembling of stubs is requested

* Revert "Dump IR for stubs only if disassembling of stubs is requested"

This reverts commit d8b56bec129bc23c2b16f1f3c6367190181b6fdb.

* Dump IR for stubs only if disassembling of stubs is requested (another approach)

* Improve overflow deoptimization for ADD(_,1) and SUB(_,1)

Now we deoptimize to the next instruction, load constant result, and remove op1 from SNAPSHOT

* Switch to IR Builder API

* Switch to new IR builder macros

* Fix jit_set_Z_TYPE_INFO() call. op3 is a simple constant (not a ir_ref).

* Generate better code

* Enable empty ENTRY block merging

* Improve code generated for array separation/creation before an update

(ASSIGN_DIM, ASSING_DIM_OP, etc)

* Fix incorrect deleteion of PHI source (op1 is used for control link)

* Load constant once

* cleanup

* Improve control-flow to avoid two IS_ARRAY checks for REFERENCEs

* Update comments

* cleanup

* Clenup comments

* Fix AAarch 64 build (disable stack adjustment auto-detection)

* Add filename and line number to closure names

* Reserve stack for parameter passing

* Increase size of CPU stack reserved for JIT-ed code

* Fix addess sanitizer warnings

* Clenup: introduce OPTIMIZE_FOR_SIZE macro (disabled by default)

* Port 08e7591206 to IR JIT

Fix (at lease part of the) #GH-10635: ARM64 function JIT causes impossible assertion

* cleanup

* Preload constant and use tests that may be compiled into better code

* Convert helpers to stubs

* Introduce a helper data structure (ir_refs) to collect references for the following use in (MERGE/PHI)_N

* Use ir_refs

* Improve code generated by zend_jit_zval_copy_deref()

* Use "cold" attribute to influence IR block scheduler and achieve better code layout

* Keep info collected by recursion analyzer

* Use HTTPS URL to allow fetching without a SSH key

* Update IR

* Update IR

* Add IR JIT support for Wondows (Win64 support is incomplete)

* Update IR

* Update IR

* Fix support for Windows ZTS build

* Fix stack alignment

* Cleanup ir_ctx.control usage

* Fixed support for irreducable (incomplete) and merged loops

* Revert "Fixed support for irreducable (incomplete) and merged loops"

This reverts commit 672b5b89f47e8b81745fb73c86e0bcb0937daf16.

* Generate better code for RECV_ENTRies

* Use simpler and more efficient checks

* Switch to new ENTRY node concept

* Limit register usage across the OSR ENTRY point

* Upate MEM type only if we write to memory

* Use LOOP_END without a reference edge

* Use new ir_init() prototype

* Delay LOAD for better LOAD fusion

* Fix RECV/RECV_INIT compilation with opcache.jit=1235

* iPtoperly compile fake closures (they mau be called as regular functions)

* Fix reabase

* Fix rebase and add --with-capstone support for IR JIT

* Replace zend_uchar -> uint8_t

* IR JIT support for delayed destructor for zend_assign_to_typed_ref/prop

* Handle zend_execute_internal in IR JIT

* Fix readonly+clone IR JIT issues

* Switch to ir_ctx.mflags

* Ckeanup "inputs_count" access

* Disable CSE for nodes bound to PHP local varibles

The stack slots for temporaty variables may be reused and in case of
spilling this may cause clobbering of the value.

(ext/standard/tests/strings/htmlentities20.phpt on x86 with tracing JIT)

* Fix deoptimization code when link traces

See ext/zlib/tests/bug75273.phpt failure

* Fix missing type store

This fixes ext/openssl/tests/openssl_error_string_basic_openssl3.phpt

* Fix tracing JIT for overflowing INC/DEC

Fixes tests/lang/operators/preinc_basiclong_64bit.phpt

* Remove ir_remove_unreachable_blocks() call. Now it's called by ir_build_cfg(), when necessary.

* IR JIT: Fixed inaccurate range inference usage for UNDEF/NULL/FALSE

* IR JIT: Fixed GH-11127 (JIT fault)

* Avoid allocation of unused exit point

* Don't record already stored PHP variables in SNAPSHOTs

* Delay variable load

* Disable CSE across ENTRY

* Fixed disabling CSE

* Fix deoptimization

* Fixed deoptimization

* Disable incorrect register allocation

* Fix JIT for INDENTICAL+JMPZ_EX

* Add comments

* Fixed missed type stores

* IR JIT: added support for CLDEMOTE

* Fixed incorrect constant usage

* Disable compilation of PHP functions with irreducible CGF

* Fixed liveness check

* Fixed code for constant conditional jump

* Add type store to avoid use-after-free

* Fixed liveness analyses

* Gnerate SNAPSHOT for virtual method calls

* More accurate search for staticaly inferred info about a trace SSA vaiable

* Fix incorrect result use type_info

* Fix JMPZ/NZ_EX support and missing type store

* Fixed trace type inference and missing type store

* Store type of unused CV to prevent possible following use after free

* Fixed deoptimizaton info

* Fixed stack layout

* Implemented support for veneers on AArch64

* Dsable CSE to avoid over-optimization

* Don't bind nodes for TMP PHP variables

* Re-enable CSE for temporary variables as we don't bind them anymore

* Switch to CPU stack spill slots

* Add codegen info dump

* Initialize CV variables through FP (this enables some folding optimizatios)

* Use zero-extension that can be eliminated

* Avoid generation of dead PHIs

* Increase preallocated spill stack size

* Enable IR based JIT by default

* Fixed build with -disable-opcache-jit

* Use explicit type conversion & force load values to registerts

* Fix IR build

* Checkout submodules in github actions

* Fixed Windows build

* Fixed Windows build

* Fixed reattach to IR JIT SHM

* Update IR

* Checkout submodules in nightly CI

* Fix MACOS ZTS in IR JIT

* Update ir

* Fixed incorrect register allocation

* Fixed incorect code generation

* Fixed tracing jit for BIND_INIT_STATIC_OR_JMP

* Update README

* Typos

* Revert JIT disabling for run-tests.php workers

* Fixed code review issues

* Update IR

* Update IR

* Update IR

* Allow exit_point duplication, when the deoptimization info differs because of spilling

* Use bound spill slots for CV (once again)

* Improve error handling

* Removed IR submodule

* Remove IR submodule from workflows

* Embed IR

IR commit: 8977307f4e96ee03847d7f2eb809b3080f9ed662

* Add .gitignore

* Fixed according to feedback

* Force C saving preserved registers only for HYBRID VM

* Update IR

IR commit: a2f8452b3d35a756cba38924f5c51a48a7207494

* cleanup

* Replace ZEND_ASSERT(0) by ZEND_UNREACHABLE()

* Update IR and remove unused IR files

IR commit: 399a38771393c202a741336643118991290b4b1b

* Fixed inconsistency between IR code-generation and register-allocation

* Update IR

IR commit: 86685504274b0c71d9985b3c926dccaca2cacf9b

* Update ir_PHI*() according to IR construction API changes

* Fixed 32-bit build

* Update IR

IR commit: d0686408e20cd8c8640e37ed52ab81403a2383cb

* Support for ir_TAILCALL() prototype changes

* Update IR

IR commit: d72ae866e09d17e879378767aceb91d51894818c

* Fixed incorrect extension (ZEXT->SEXT)

* Fix SSA dominance

* Update IR

IR commit: d60d92516dc5f89b93cdf1df7a54141e83226b07

* Fixed support ir_ctx.ret_type
2023-10-23 10:15:52 +03:00
Ilija Tovilo
73c5f36f5b
Assert ptr_ptr value of TMP|CONST isn't used (#11865)
We require valid code for compilation to succeed, but these paths should always
be guarded by OPx_TYPE checks and never execute. Add an assertion to verify.
2023-08-03 15:28:19 +02:00
Max Kellermann
d5c649b36b
zend_compiler, ...: use uint8_t instead of zend_uchar (#10621)
`zend_uchar` suggests that the value is an ASCII character, but here,
it's about very small integers.  This is misleading, so let's use a
C99 integer instead.

On all architectures currently supported by PHP, `zend_uchar` and
`uint8_t` are identical.  This change is only about code readability.
2023-02-23 14:56:54 +00:00
Ilija Tovilo
02bd52b5a8
Implement dynamic class const fetch
https://wiki.php.net/rfc/dynamic_class_constant_fetch

Closes GH-9793
2023-01-26 16:46:34 +01:00
Ilija Tovilo
3f7ec69b61
Collapse more generated files in PRs (#8754)
* The generated VM files
* tokenizer_data.c
2022-06-12 10:56:35 +02:00
Bob Weinand
b4285e5546 Ensure vm_spec_handlers exists for all opcodes <= 255 so that user defined higher opcodes do not read outside buffer
This largely has no effect in practice, but ASAN will complain then.
2022-05-25 11:28:34 +02:00
Ilija Tovilo
9a90bd7054
Deprecate ${} string interpolation
https://wiki.php.net/rfc/deprecate_dollar_brace_string_interpolation
2022-05-05 10:14:56 +02:00
Nikita Popov
55a4bae546 Merge branch 'PHP-8.1'
* PHP-8.1:
  Handle holes in zend_get_opcode_id()
2021-12-30 16:56:10 +01:00
Nikita Popov
b63e4cf727 Handle holes in zend_get_opcode_id()
Some opcodes may currently not be allocated.
2021-12-30 16:56:03 +01:00
Dmitry Stogov
c8dca00d15 Merge branch 'PHP-8.1'
* PHP-8.1:
  Fix clobering of operand by error handler in assignment to string offset
2021-12-02 01:22:15 +03:00
Dmitry Stogov
9786eac9a3 Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0:
  Fix clobering of operand by error handler in assignment to string offset
2021-12-02 00:46:27 +03:00
Dmitry Stogov
09547c64c2 Fix clobering of operand by error handler in assignment to string offset
In some cases new code requires two reallocations insead of one.

Fixes oss-fuzz #31716, #36196, #39739 and #40002
2021-12-02 00:24:05 +03:00
Nikita Popov
cacafd36a7 Merge branch 'PHP-8.1'
* PHP-8.1:
  Suppress unused label warnings in SWITCH VM
2021-11-04 14:52:53 +01:00
Nikita Popov
5d2f3d45cc Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0:
  Suppress unused label warnings in SWITCH VM
2021-11-04 14:52:45 +01:00
Nikita Popov
ee37774466 Suppress unused label warnings in SWITCH VM
While we avoid emitting labels for handlers that are not referenced
from anywhere else, we do not perform a fine-grained analysis on
used specializations, so some of the specialization labels may not
be used. Use ATTRIBUTE_UNUSED_LABEL to suppress the warning. Drop
"cold" from the definition of this attribute, as it is completely
unrelated.
2021-11-04 14:50:54 +01:00
Nikita Popov
da0d246e19 Drop FREE_OP_VAR_PTR() distinction
FREE_OP_VAR_PTR() is like FREE_OP(), but only frees VAR, rather
than VARs and TMPs. I don't think this distinction makes sense
anymore, as opcodes using FREE_OP_VAR_PTR() generally only accept
VAR or CV. For the cases where other op types are accepted and
only freeing VAR is desired we already have FREE_OP_IF_VAR().

This drops FREE_OP_VAR_PTR(), leaving only FREE_OP() and
FREE_OP_IF_VAR().
2021-10-20 12:02:09 +02:00
Nikita Popov
58a0c5a2e1 Remove stale variables from zend_vm_gen.php
These "unfetched" variants no longer exist.
2021-10-19 12:27:54 +02:00
Kamil Tekiela
c3dda473cc
Fix 'can not' in test data and in code comments 2021-10-05 09:51:58 +01:00
Hao Sun
60ea2cbf74
Fix a typo in function execute_ex (#7315) 2021-07-29 13:49:31 +02:00
Dmitry Stogov
5fe2062585 Correct DWARF frame description.
Now GDB correctly shows backtraces that involves JIT-ed code for
functional/tracing JIT, HYBRID/CALL VM, x86/AArch64 CPU.
(opcache.jit_debug=0x100 should be set).
2021-05-18 18:21:08 +03:00
Dmitry Stogov
997374f41c Disable "red zone" usage (it leads to crashes). 2021-05-18 15:32:31 +03:00
Dmitry Stogov
57f2fe44c6 Use "red zone" for HYBRID VM.
Support for CALL VM and VM without global register variables.
2021-05-18 15:32:31 +03:00
Nikita Popov
57eb29f1d3 Update zend_vm_gen.php with zend_vm_opcode.c/h changes
The generated files were modified directly, resulting in mysterious
build failures depending on exact build order.
2021-04-06 11:35:05 +02:00
Max Semenik
b86dfb0e74 Fix E_DEPRECATED in zend_vm_gen.php
explode(): Passing null to parameter #2 ($string) of type string is
deprecated

Closes GH-6698.
2021-03-01 11:22:18 +01:00
Nikita Popov
de5b42219c Avoid writing zend_vm_opcodes.h if it did not change
Now that we track header changes, a change to zend_vm_opcodes.h
requires rebuilding essentially the whole tree. In most cases,
changes to zend_vm_def.h don't actually result in any header
changes though.

Avoid touching the file by first checking whether the to be written
contents are actually the same.
2021-02-17 17:18:57 +01:00
Alex Erohin
cbfdc1fd54 Coding style tweaks for zend_vm_gen.php
- fixed array style for $vm_kind_name and $op_types
- deleted unnecessary else statement for is_hot_helper function
- fixed concatenation style
- fixed style of using whitespace between "(" and switch/foreach - replaced !is_null with "!=="

Closes GH-6704.
2021-02-17 17:05:34 +01:00
Dmitry Stogov
8ad2b59e12 Disable stack reuse optimization for x86 PIC code. It may clobber local variable used for Global Offset Table. 2020-12-01 15:20:06 +03:00
Dmitry Stogov
841b00f641 Preallocate stack space for JIT in execute_ex() to eliminate JIT prologue/epilogue. 2020-11-30 17:56:08 +03:00
Sammy Kaye Powers
58d41b8c4f Provide unused retvals to observers
Make sure that the return value is available to observers, even if
it is not used by the caller.

Closes GH-6422.
2020-11-17 10:28:47 +01:00
Dmitry Stogov
855d8fa68f [Observer] Save opline before calling begin/end handlers 2020-11-11 13:06:55 +03:00
Dmitry Stogov
d5d31ea3b3 Cleanup observer API and add JIT support 2020-09-18 12:55:58 +03:00
Sammy Kaye Powers
9e94bcfdbc Remove specialization of SPEC(OBSERVER) handlers 2020-09-18 00:47:36 +03:00
Levi Morrison
66c3e900e2 Add zend_observer API
Closes GH-5857.

Co-authored-by: Nikita Popov <nikita.ppv@gmail.com>
Co-authored-by: Sammy Powers <sammyk@datadoghq.com>
2020-09-01 09:59:59 -06:00
Nikita Popov
42eda5160d SAVE_OPLINE in NULL_HANDLER
Let's avoid crashing before the nice error message gets printed...
2020-08-11 15:14:50 +02:00
Nikita Popov
d92229d8c7 Implement named parameters
From an engine perspective, named parameters mainly add three
concepts:

 * The SEND_* opcodes now accept a CONST op2, which is the
   argument name. For now, it is looked up by linear scan and
   runtime cached.
 * This may leave UNDEF arguments on the stack. To avoid having
   to deal with them in other places, a CHECK_UNDEF_ARGS opcode
   is used to either replace them with defaults, or error.
 * For variadic functions, EX(extra_named_params) are collected
   and need to be freed based on ZEND_CALL_HAS_EXTRA_NAMED_PARAMS.

RFC: https://wiki.php.net/rfc/named_params

Closes GH-5357.
2020-07-31 15:53:36 +02:00
Nikita Popov
613a56d1cb Remove FREE_UNFETCHED concept
In master normal FREE_OPs work like FREE_UNFETCHED_OP used to, so
there is no point in keeping this distinction anymore, it's just
confusing.
2020-07-09 11:58:33 +02:00
Nikita Popov
5d0687e895 Assert exception set in HANDLE_EXCEPTION()
Some code paths were checking this manually, but we can turn this
into a general assertion to avoid surprises (functions returning
failure without throwing).
2020-07-07 11:31:05 +02:00
Nikita Popov
fb91611276 Remove #undefs from vm_gen
Possibly these were needed for VM_EXPORT, but they don't serve a
purpose now.
2020-07-07 11:25:28 +02:00
Nikita Popov
002c264d07 Remove ZEND_VM_EXPORT functionality
This hasn't been used since forever and makes things more confusing
than they already are.
2020-07-07 11:23:28 +02:00
Ayesh Karunaratne
d114812faf [ci skip] Various typo fixes in stub comments and CHANGES file 2020-06-25 23:32:40 +02:00
Dmitry Stogov
f4b46314f6 Prevent CGG reordering if hanlers order is defined by zend_vm_order.txt 2020-05-22 12:37:35 +03:00
Nikita Popov
d4de3f95d6 Remove spurious const qualifier from function return type 2020-02-06 11:59:52 +01:00
Nikita Popov
169805777c Merge branch 'PHP-7.4'
* PHP-7.4:
  Apply tidy formatting
2020-02-03 13:42:08 +01:00
Nikita Popov
58b17906f5 Apply tidy formatting
Mostly reindent PHP scripts to spaces.
2020-02-03 13:41:31 +01:00
Tyson Andre
a7580899f3 Support the same handler for multiple opcodes 2019-11-15 17:37:01 +03:00
Tyson Andre
e8525c2f68 Optimize int === int/double === double
Do this by reusing the implementation used for `==`
when both arguments are ints (IS_LONG) or both are floats (IS_DOUBLE)

```php
// Before: nestedloop_ni took 0.442 seconds
// After: nestedloop_ni takes 0.401 seconds (same as nestedloop_ne)
function nestedloop_ni(int $k) {
  $x = 0;
  for ($i=0; $i < 50000000; $i++) {
    if ($i === $k) {
      $x++;
    }
  }
  print "$x\n";
}
function nestedloop_ne(int $k) {
  $x = 0;
  for ($i=0; $i < 50000000; $i++) {
    if ($i == $k) {
        $x++;
    }
  }
  print "$x\n";
}
```
2019-11-15 17:37:01 +03:00