Repository navigation
Conversation
flatten_trait_into_class looked up each trait's methods by scanning every function of the registry, and every flattened method appends more of them. A file with many trait-using classes paid O(classes x functions), and the scan grew with its own output. The class-field pass now keeps a receiver -> function-id index, synced incrementally as functions are registered, and flattening reads only the trait's own entries registered before the current class. If the index cannot be built, the previous full scan runs unchanged. Only entries registered before flattening started are visited, so the output is identical. Tests: the work-counter tests for #1265 (100 -> 200 trait-using classes, ratio gate 2.5) and #765 (trait collision shapes stay bounded) use the existing test-only work ceiling. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
The class-field pass stored the address of a stack-local index in ctx for the duration of the pass. It was restored before returning, but the pattern is what cppcheck's autoVariables check rejects. The index now lives in the call's arena; on an allocation failure it stays NULL and flattening runs the full scan, as before. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
…-index Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This branch has not been deployed
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.
What
flatten_trait_into_class(PHP LSP) found each trait's methods by scanning every function in the registry. Every flattened method adds more functions, so the scan grows with its own output. A file with many trait-using classes paid O(classes × functions) (#1265).The class-field pass now keeps a receiver -> function-id index, updated incrementally as functions are registered. Flattening reads only the trait's own entries that were registered before the current class:
Evidence
Graph identity, from a clean build of this branch (7dc07d9 on main 4527fc7, build log from scratch) against a clean build of main c06465b, parallel:
All three are trait-heavy. The only commit between c06465b and 4527fc7 is fix(php): index the single-file LSP type registry #2702, which also preserves output, so the comparison covers both changes together. An earlier combined build was also byte-identical on every PHP and C# corpus repo, parallel and sequential. That build held this change, fix(php): index the single-file LSP type registry #2702 and the iterative C# walker.
Work counter (
CBM_LSP_WORK, deterministic, no clock), using the test-only work ceiling from fix(php): index the single-file LSP type registry #2702:phplsp_trait_flatten_work_is_linear_issue1265, 100 -> 200 trait-using classes, gate: ratio ≤ 2.5.phplsp_trait_collision_shapes_bounded_work_issue765: trait collision shapes (PHP: trait whose name collides with an aliaseduse … asimport it composes → unbounded recursion indefinitionspass, OOM (SIGKILL) #765) stay bounded. Work is 1,225 without the index and 343 with it. Main does not reproduce PHP: trait whose name collides with an aliaseduse … asimport it composes → unbounded recursion indefinitionspass, OOM (SIGKILL) #765, so this test pins the behaviour instead of fixing a red case.Suites on 7dc07d9 (ASan test-runner):
php_lsp,parallel,pipeline,complexityandincremental, 941 passed.Lint:
internal/cbm/lsp/is outside CI'sLINT_SRCS/LINT_HDRS, so I ran the gates directly on the changed files.php_lsp.halready differs from clang-format on main, outside this diff.autoVariables: the pass stored the address of a stack-local index in the context. The pointer was restored before return, but the second commit moves the index into the arena, and the warning is gone. One existing style note remains (redundantInitializationofqualifiedinphp_lsp.c), outside this diff.Head e9b334e merges main 27c3303. Main has not touched
php_lsp.c,php_lsp.hortests/test_php_lsp.csince 4527fc7, and merge-tree is clean.Fixes #1265. Refs #765.