[GR-54862] Fix scalability bottlenecks in the static analysis. #9169
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.
This PR re-works how we collect all method implementations, used e.g. for building vtables and for method-override-notifications. We had two performance problems in the static analysis:
AnalysisUniverse.collectMethodImplementations
was an expensive serial operation, running every time after analysis has reached a fixed point.AnalysisMethod.processMethodOverrides
needed to check all methods for possible override-notifications (even though only few methods actually have a notification handler registered). It calledAnalysisType.findMethod
, which iterated through all declared methods to find a match.I concluded that it is too difficult to maintain the complete and correct set of all reachable method overrides during the parallel analysis. When a method becomes reachable, it is too expensive to find all other methods that it possibly overrides. Therefore, the new approach now collects all possible implementations (even not reachable methods) whenever a new type becomes reachable or a new method is created. The correctly filtered list of all reachable implementations is produced on demand.
This means method override notifications can no longer be called during the parallel analysis. This is now done every time the analysis reaches a fixed point. In case that there are new notifications, the tasks are scheduled and the parallel analysis is restarted. While this is not ideal, I do not see a better way of handling this. It is certainly faster than before, because there are only few method override notifications registered.
In addition, this PR fixes a few other performance problems I spotted while looking at profiles, e.g., when we had de-generated hash maps due to bad hash code implementations; or where we need to cache frequently accessed information.