Skip to content

Performance optimisations: split debugger init into two parts and defer the heavy one#13

Closed
pronskiy wants to merge 3 commits intomainfrom
autoresearch-2
Closed

Performance optimisations: split debugger init into two parts and defer the heavy one#13
pronskiy wants to merge 3 commits intomainfrom
autoresearch-2

Conversation

@pronskiy
Copy link
Owner

  • Split xdebug_debugger_rinit() into rinit_early() (IDE key, context) and rinit() (opcache disable, breakable_lines_map). Full rinit only runs after successful IDE connection.
  • Restructure RINIT to move trigger/connection check before library and base init. Added dormant init paths (xdebug_library_rinit_dormant, xdebug_base_rinit_dormant) that skip fiber_stacks, stack vector, trait_location_map, headers, diagnosis_buffer, filters, error handler overrides. Added NULL guards to all cleanup paths.

pronskiy and others added 3 commits March 14, 2026 22:09
Split xdebug_debugger_rinit() into two phases:
- rinit_early(): minimal setup (IDE key, no_exec, context init)
- rinit(): heavy work (opcache disable, breakable_lines_map alloc)

The full rinit() now only runs when an IDE client actually connects.
When no IDE is listening (the common case with triggers), we skip:
- breakable_lines_map hash allocation (2048 buckets)
- xdebug_disable_opcache_optimizer() INI modifications
- related string allocations

Mid-request connections (xdebug_break, start_upon_error) lazily
call xdebug_debugger_rinit() via xdebug_init_debugger().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Restructure RINIT to move the trigger/connection check before heavy
allocations. When no IDE is listening (the common case), the extension
now uses dormant init paths that skip:

- xdebug_library_rinit: diagnosis_buffer, headers list, trait_location_map
  (256-bucket hash), log file open, path mapping
- xdebug_base_rinit: fiber_stacks (64-bucket hash), stack vector,
  filters linked list, closure serializer, control socket, error/exception
  handler overrides

Added NULL guards to all cleanup paths and the fiber switch observer
to handle the dormant state safely.

This eliminates all per-request heap allocations when no debugger
will connect, reducing overhead for short-lived PHP-FPM requests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract xdebug_library_rinit_log() to open diagnosis_buffer and log
file early in RINIT, before the trigger/connection check. This ensures
log messages from trigger evaluation (XDEBUG_IGNORE, trigger mismatch)
and connection attempts are captured even on the dormant path.

Fixes tests: bug01978, bug02348, start_ignore_yes_env,
start_with_request_trigger_match-009, trigger_match-010.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@pronskiy pronskiy closed this Mar 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant