JDK-8273563 : Improve performance of implicit exceptions with -XX:-OmitStackTraceInFastThrow
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 18,19
  • Priority: P4
  • Status: In Progress
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2021-09-09
  • Updated: 2022-06-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
Description
Currently, if running with -XX:-OmitStackTraceInFastThrow, C2 has no possibility to create implicit exceptions like AIOOBE, NullPointerExceptions, etc. in compiled code with the effect that these methods will always be deoptimized and reexecuted in the interpreter if such an exception is happening.

If such implicit exceptions are used for normal control flow, that can have a dramatic impact on performance. A prominent example for such code is Tomcat's HttpParser::isAlpha() method[1]:

    public static boolean isAlpha(int c) {
        try {
            return IS_ALPHA[c];
        } catch (ArrayIndexOutOfBoundsException ex) {
            return false;
        }
    }

Instead of deoptimizing and resorting to the interpreter, we can generate code which allocates and initializes the corresponding exceptions right in compiled code.

A prototype which implements this idea shows a ten-times performance improvement for the above code:

-XX:-OmitStackTraceInFastThrow
Benchmark                 (exceptionProbability)  Mode  Cnt      Score      Error  Units
ImplicitExceptions.bench                     0.0  avgt    5      1.430 ±    0.353  ns/op
ImplicitExceptions.bench                    0.33  avgt    5   3563.038 ±   77.358  ns/op
ImplicitExceptions.bench                    0.66  avgt    5   8609.693 ± 1205.104  ns/op
ImplicitExceptions.bench                    1.00  avgt    5  12842.401 ± 1022.728  ns/op

-XX:-OmitStackTraceInFastThrow -XX:+OptimizeImplicitExceptions
Benchmark                 (exceptionProbability)  Mode  Cnt     Score     Error  Units
ImplicitExceptions.bench                     0.0  avgt    5     1.432 ±   0.352  ns/op
ImplicitExceptions.bench                    0.33  avgt    5   355.723 ±  16.641  ns/op
ImplicitExceptions.bench                    0.66  avgt    5   887.068 ± 166.728  ns/op
ImplicitExceptions.bench                    1.00  avgt    5  1274.418 ±  88.235  ns/op

[1] https://github.com/apache/tomcat/blob/26ba86cdbd40ca718e43b82e62b3eb49d004c3d6/java/org/apache/tomcat/util/http/parser/HttpParser.java#L266-L274
Comments
Moving to JDK 19 as the fork is done today.
09-12-2021

Yes, I agree.
02-12-2021

I've looked at the tests. The following two test: compiler/intrinsics/klass/CastNullCheckDroppingsTest.java compiler/profiling/TestTypeProfiling.java will pass with '-XX:-OmitStackTraceInFastThrow' once this change will be pushed. So there's probably no need for action. The remaining two test: compiler/loopopts/TestDivZeroCheckControl.java#id0 compiler/loopopts/TestSkeletonPredicateNegation.java are failing due to timeouts if running with '-XX:-OmitStackTraceInFastThrow' (even with this change). E.g. with this change and '-XX:-OmitStackTraceInFastThrow', "TestDivZeroCheckControl.java#id0" runs 7min compared to 22min before. That's three times faster but still way above the default timeout of two minutes. So I think it makes sense to add '-XX:+OmitStackTraceInFastThrow' together with a small comment why we need it to them. Will do it in the next version of my PR. Do you agree?
02-12-2021

I run our tier1 testing without proposed changes and with '-XX:-OmitStackTraceInFastThrow'. I got 4 tests failed because they see unexpected deoptimizations (we generate uncommon trap when OmitStackTraceInFastThrow is off): compiler/intrinsics/klass/CastNullCheckDroppingsTest.java compiler/loopopts/TestDivZeroCheckControl.java#id0 compiler/loopopts/TestSkeletonPredicateNegation.java compiler/profiling/TestTypeProfiling.java Should we fix these tests too (add -XX:+OmitStackTraceInFastThrow to them)?
02-12-2021