Avoid eagerly creating the default font as a side effect in FontRegistry - #4265
Avoid eagerly creating the default font as a side effect in FontRegistry#4265HeikoKlare wants to merge 1 commit into
Conversation
When put() replaced an already-realized font, it obtained the current default font via defaultFontRecord() purely to compare it against the replaced font's instances for staleness. defaultFontRecord() does not just look up an already-realized default font, it also creates and caches one if none exists yet. As a result, replacing an unrelated symbolic name's font could silently allocate and cache a native default-font handle earlier than it would otherwise have been needed, merely as a side effect of an identity comparison. Creating that font is not the only consequence. createFont() registers the data it used under the symbolic name it created the font for, so replacing an unrelated font also registered font data for the default font that no client ever asked for. That is directly observable: hasValueFor(JFaceResources.DEFAULT_FONT) flipped to true, and getKeySet() started reporting the default font, purely because some other name had been re-put. Look up the already-cached default font record directly instead, tolerating that it may not exist yet (in which case the replaced font's instances are unconditionally treated as stale, same as before, since they can never equal a still-unrealized default font). Add a regression test asserting that replacing a realized font leaves the default font unregistered. Beyond the observable effect above, this also matters once the font cache stops being a single shared cache, so that comparing against a display's default font does not have the side effect of allocating that default font on an unrelated display. Assisted-by: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates FontRegistry.put() to avoid eagerly realizing/creating the default font as an observable side effect when replacing an already-realized non-default font. This prevents hasValueFor(JFaceResources.DEFAULT_FONT) and getKeySet() from changing solely due to identity comparisons during stale-font retirement.
Changes:
- Update
FontRegistry.put(...)to look up an already-cached defaultFontRecorddirectly (and tolerate it being absent) instead of callingdefaultFontRecord(). - Add a regression test ensuring replacing a realized font does not register the default font name/data.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
bundles/org.eclipse.jface/src/org/eclipse/jface/resource/FontRegistry.java |
Avoids default font realization/registration side effects during stale-font handling when replacing an existing realized font. |
tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/resources/FontRegistryTest.java |
Adds coverage asserting put() replacement does not implicitly register the default font. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
fedejeanne
left a comment
There was a problem hiding this comment.
Looks good, I would also remove the now unused method addAllocatedFontsToStale since it's part of private class FontRecord.
@fedejeanne I think I do not understand that comment. The method belongs to the |
fedejeanne
left a comment
There was a problem hiding this comment.
Nevermind, I just noticed that the method is removed in #4269 so it's all good 👍
When
put()replaces an already-realized font, it obtains the current default font viadefaultFontRecord()purely to compare it against the replaced font's instances for staleness. ButdefaultFontRecord()does not just look up an already-realized default font — it also creates and caches one if none exists yet.So replacing an unrelated symbolic name's font allocates a native default-font handle earlier than needed, merely as a side effect of an identity comparison. And because
createFont()registers the data it used, this is directly observable:hasValueFor(JFaceResources.DEFAULT_FONT)flips totrueandgetKeySet()starts reporting the default font, purely because some other name was re-put.Look up the already-cached default font record directly instead, tolerating that it may not exist yet — in which case the replaced font's instances are unconditionally treated as stale, exactly as before, since they can never equal a still-unrealized default font.
Includes a regression test asserting that replacing a realized font leaves the default font unregistered.
🤖 Generated with Claude Code