Skip to content

Avoid per-paint allocations for code minings - #4480

Merged
vogella merged 1 commit into
eclipse-platform:masterfrom
vogella:lv/codemining-paint-allocations
Oct 15, 2026
Merged

vogella merged 1 commit into
eclipse-platform:masterfrom
vogella:lv/codemining-paint-allocations

Conversation

@vogella

@vogella vogella commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Code minings split their labels with a line break regular expression that String.split cannot fast-path, so a Pattern was compiled on every line height computation and every draw, and the following mining's label was split completely just to read its first line. InlinedAnnotationDrawingStrategy also fetched the native font data of the widget font and the annotation font on every draw to check whether its cached italic font was still valid. The pattern is now compiled once, the first line is found with a scan, and the drawing strategy only compares font data when the widget font instance changes, registering its dispose listener once per widget. This removes several allocations and native calls from the paint path of editors with code minings, and a label consisting only of line breaks now yields an empty first line instead of an ArrayIndexOutOfBoundsException.

@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Test Results

   867 files  ±0     867 suites  ±0   53m 32s ⏱️ + 4m 58s
 8 463 tests +2   8 221 ✅ +2  242 💤 ±0  0 ❌ ±0 
21 267 runs  +6  20 584 ✅ +6  683 💤 ±0  0 ❌ ±0 

Results for commit 37da6aa. ± Comparison against base commit 3d25b65.

♻️ This comment has been updated with latest results.

@vogella
vogella force-pushed the lv/codemining-paint-allocations branch 2 times, most recently from 63a5df5 to 08ca5fa Compare October 14, 2026 22:16
Computing line heights and drawing code minings split labels with a
regular expression that String.split cannot fast-path, so a Pattern was
compiled on every call, and the next mining's label was split entirely
just to read its first line. The inlined annotation drawing strategy
also queried the native font data of the widget font and of the
annotation font on every draw to decide whether the cached italic font
was still valid, and only compared heights, so a font family change kept
the stale italic font.

The line break pattern is now compiled once, the first line is found
with a scan, and hasAtLeastOneResolvedMiningNotEmpty uses plain loops.
The drawing strategy remembers which widget font its annotation font was
derived from and recreates it whenever the widget font changes.
The dispose listener is registered once per widget instead of each time
the font is recreated. A label made only of line breaks no longer throws
an ArrayIndexOutOfBoundsException and no longer reduces the line count
of a multi-mining header.

Assisted-by: multiple AI agents and layers of automated tooling 🤖
@vogella
vogella force-pushed the lv/codemining-paint-allocations branch from 08ca5fa to 37da6aa Compare October 14, 2026 22:43
@vogella
vogella requested a balanced review from Copilot October 15, 2026 05:03

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The localized changes have regression coverage and no identified blocking issues; tests were not executed.

0 open findings

What changed in this PR

Reduces allocations and native font calls when rendering JFace code minings.

Changes:

  • Reuses compiled line-break patterns and scans for the next label’s first line.
  • Caches annotation fonts by widget font, with one disposal listener per widget.
  • Adds regression tests for font lifecycle and line-break handling.
File Description
tests/​org.eclipse.jface.text.tests/​src/​org/​eclipse/​jface/​text/​tests/​source/​inlined/​InlinedAnnotationFontTest.java Tests font replacement, reuse, and disposal.
tests/​org.eclipse.jface.text.tests/​src/​org/​eclipse/​jface/​text/​tests/​JFaceTextTestSuite.java Registers the font regression test.
tests/​org.eclipse.jface.text.tests/​src/​org/​eclipse/​jface/​text/​tests/​codemining/​CodeMiningLineHeaderAnnotationTest.java Tests multiline height and line-break-only labels.
bundles/​org.eclipse.jface.text/​src/​org/​eclipse/​jface/​text/​source/​inlined/​InlinedAnnotationDrawingStrategy.java Caches derived fonts and simplifies disposal.
bundles/​org.eclipse.jface.text/​src/​org/​eclipse/​jface/​text/​codemining/​LineHeaderCodeMining.java Reuses a compiled pattern during drawing.
bundles/​org.eclipse.jface.text/​src/​org/​eclipse/​jface/​internal/​text/​codemining/​CodeMiningLineHeaderAnnotation.java Reduces height-calculation allocations and handles empty split results.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@vogella
vogella merged commit a370483 into eclipse-platform:master Oct 15, 2026
18 checks passed
@vogella
vogella deleted the lv/codemining-paint-allocations branch October 15, 2026 05:09
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.

2 participants