Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slow decompiler highlighting #7520

Open
sad-dev opened this issue Feb 18, 2025 · 2 comments
Open

Slow decompiler highlighting #7520

sad-dev opened this issue Feb 18, 2025 · 2 comments
Assignees
Labels
Status: Internal This is being tracked internally by the Ghidra team
Milestone

Comments

@sad-dev
Copy link
Contributor

sad-dev commented Feb 18, 2025

Describe the bug
When the existing number of highlighters that apply to a function is large (global highlighters + secondary for that function), the computation of token highlights is extremely slow. This is made worse by #3749 which prevents a user from creating a secondary highlight, meaning all highlights are global and will apply to all functions.

The responsible code path for global highlights is as follows (there is a similar path for secondary highlights)
Note the multiple iterations over highlighters (as well as double call to clearHighlights) which causes unnecessary quadratic complexity in computation.
There may also be other similar issues in the code for clearing highlights

DecompilerPanel.reapplyGlobalHighlights
		Set<DecompilerHighlighter> globalHighlighters = highlightController.getGlobalHighlighters();
		for (DecompilerHighlighter highlighter : globalHighlighters) {
			highlighter.clearHighlights();
			highlighter.applyHighlights();
		}
ClangDecompilerHighlighter.applyHighlights
		clearHighlights();
		Map<ClangToken, Color> highlights = new HashMap<>();
		try {
			matcher.start(root);
			gatherHighlights(root, highlights);
		}
		finally {
			matcher.end();
		}
		Supplier<? extends Collection<ClangToken>> tokens = () -> highlights.keySet();
		ColorProvider colorProvider = new MappedTokenColorProvider(highlights);
		decompilerPanel.addHighlighterHighlights(this, tokens, colorProvider);
DecompilerPanel.addHighlighterHighlights
ClangHighlightController.addHighlighterHighlights
ClangHighlightController.addTokensToHighlights
		for (ClangToken clangToken : tokens) {
			Color color = colorProvider.getColor(clangToken);
			doAddHighlight(clangToken, color, currentHighlights);
		}
ClangHighlightController.doAddHighlight
ClangHighlightController.updateHighlightColor
ClangHighlightController.getCombinedColor
ClangHighlightController.blendHighlighterColors
		Set<DecompilerHighlighter> global = getGlobalHighlighters();
		Set<DecompilerHighlighter> secondary = getSecondaryHighlighters(function);
		Iterable<DecompilerHighlighter> it = CollectionUtils.asIterable(global, secondary);
		Color lastColor = null;
		for (DecompilerHighlighter highlighter : it) {
		        ...
                }
@dragonmacher dragonmacher self-assigned this Feb 18, 2025
@dragonmacher dragonmacher added the Status: Triage Information is being gathered label Feb 18, 2025
@dragonmacher
Copy link
Collaborator

How many highlighters does it take for you to notice this behavior?

@sad-dev
Copy link
Contributor Author

sad-dev commented Feb 18, 2025

Roughly 30 highlighters that apply to a function with hundreds of highlighted tokens is enough to impose noticeable (>30s) delays

@dragonmacher dragonmacher added Status: Internal This is being tracked internally by the Ghidra team and removed Status: Triage Information is being gathered labels Mar 11, 2025
@ryanmkurtz ryanmkurtz added this to the 11.4 milestone Mar 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Internal This is being tracked internally by the Ghidra team
Projects
None yet
Development

No branches or pull requests

3 participants