Fix GH-21267: JIT infinite loop on FETCH_OBJ_R with IS_UNDEF property#21368
Open
iliaal wants to merge 1 commit intophp:masterfrom
Open
Fix GH-21267: JIT infinite loop on FETCH_OBJ_R with IS_UNDEF property#21368iliaal wants to merge 1 commit intophp:masterfrom
iliaal wants to merge 1 commit intophp:masterfrom
Conversation
When JIT compiles a side trace for FETCH_OBJ_R on a known property, the IS_UNDEF guard was conditionally skipped when a result type guard (MAY_BE_GUARD) was present. The assumption was that deoptimization from the result type guard would handle IS_UNDEF via the interpreter. However, when a side trace replaces opline->handler with JIT code, the deoptimization path dispatches back to opline->handler which now points to the JIT entry, creating an infinite loop that never reaches the interpreter or exit counter logic. Always generate the IS_UNDEF guard on hot traces regardless of MAY_BE_GUARD presence. Fixes phpGH-21267
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #21267
When JIT compiles a side trace for
FETCH_OBJ_Ron a known property, theIS_UNDEFguard was conditionally skipped when a result type guard (MAY_BE_GUARD) was present andcurrent_framewas set. The assumption was that deoptimization from the result type guard would handleIS_UNDEFby dispatching toopline->handlerto re-execute in the interpreter.However, when a side trace is compiled and linked into the parent trace's exit stub, it replaces
opline->handlerwith the JIT code entry point. Whenunset()makes a propertyIS_UNDEF, the deoptimization path jumps toopline->handlerwhich now points back to the same JIT code, creating an infinite loop. The loop never callszend_jit_trace_exit(), so no exit counters are bumped and no blacklisting occurs.The fix removes the conditional skip and always generates the
IS_UNDEFguard on hot traces, ensuring the exit stub is taken when the property is undefined.Test note:
gh21267.phptoverridesopcache.jit_hot_*counters to defaults because run-tests.php forces them to 1, which changes trace compilation order and prevents the bug from triggering.