RFR: JDK-8269921 Text in Textflow and listeners on bounds can cause endless loop/crash and other performance issues
Kevin Rushforth
kcr at openjdk.java.net
Tue Jul 6 15:02:07 UTC 2021
On Tue, 6 Jul 2021 14:53:24 GMT, Florian Kirmaier <fkirmaier at openjdk.org> wrote:
> It's "a bit" complicated.
> In some situations, getRuns get's called because listeners on bounds are set.
> This causes TextFlow to layout to compute the runs.
> Afterward, the bounds of the parents get updated.
> This triggers a call to compute bounds - which cascades up to the children.
> When the geometry of the previous Text gets computed in this big stack - it throws an nullpointer.
> The Text doesn't have its runs, and calling TextFlow.layout is now a noop (it detects repeated calls in the same stack)
>
> In the case it happened - it didn't repair and the application kinda crashed.
> This bug most likely can also be triggered by ScenicView or similar tools, which sets listeners to the bounds.
> It also can cause unpredictable performance issues.
>
> Unit test and example stacktrace are in the ticket.
>
> The suggested fix makes sure that recomputing the geometry of the Text, doesn't trigger the layout of the TextFlow.
> The Textflow should be layouting by the Parent.
> This might change the behavior in some cases, but as far as I've tested it works without issues in TextFlow Heavy applications.
>
> Benefits:
> * Better Tooling Support For ScenicView etc.
> * Fixes complicated but reproducible crashes
> * Might fix some rare crashes, which are hard to reproduce
> * Likely improves performance - might fix some edge cases with unpredictable bad performance
modules/javafx.graphics/src/main/java/javafx/scene/text/Text.java line 386:
> 384: private GlyphList[] getRuns() {
> 385: if (textRuns != null) return textRuns;
> 386: if (!isSpan()) {
Removing the call to `getParent().layout()` here seems very likely to cause a regression in behavior. This will need some further analysis and lots of testing.
tests/system/src/test/java/test/javafx/scene/text/TextFlowCrashTest.java line 1:
> 1: package test.javafx.scene.text;
This needs a standard copyright header block.
-------------
PR: https://git.openjdk.java.net/jfx/pull/564
More information about the openjfx-dev
mailing list