diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/runtime/src/main/java/io/quarkus/resteasy/reactive/server/runtime/QuarkusResteasyReactiveRequestContext.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/runtime/src/main/java/io/quarkus/resteasy/reactive/server/runtime/QuarkusResteasyReactiveRequestContext.java index 2e65c76cd2611..fb47a5faf78e4 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/runtime/src/main/java/io/quarkus/resteasy/reactive/server/runtime/QuarkusResteasyReactiveRequestContext.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/runtime/src/main/java/io/quarkus/resteasy/reactive/server/runtime/QuarkusResteasyReactiveRequestContext.java @@ -69,4 +69,52 @@ public void handleUnmappedException(Throwable throwable) { private RuntimeException sneakyThrow(Throwable e) throws E { throw (E) e; } + + /** + * The implementation looks like it makes no sense, but it in fact does make sense from a performance perspective. + * The idea is to reduce the use instances of megamorphic calls into a series of instance checks and monomorphic calls. + * The rationale behind this is fully explored in + * https://shipilev.net/blog/2015/black-magic-method-dispatch/#_cheating_the_runtime_2 + * and this specific instance has been verified experimentally to result in better performance. + */ + @Override + protected void invokeHandler(int pos) throws Exception { + var handler = handlers[pos]; + if (handler instanceof org.jboss.resteasy.reactive.server.handlers.MatrixParamHandler) { + handler.handle(this); + } else if (handler instanceof io.quarkus.resteasy.reactive.server.runtime.security.SecurityContextOverrideHandler) { + handler.handle(this); + } else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.RestInitialHandler) { + handler.handle(this); + } else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.ClassRoutingHandler) { + handler.handle(this); + } else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.AbortChainHandler) { + handler.handle(this); + } else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.NonBlockingHandler) { + handler.handle(this); + } else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.BlockingHandler) { + handler.handle(this); + } else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.ResourceRequestFilterHandler) { + handler.handle(this); + } else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.InputHandler) { + handler.handle(this); + } else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.RequestDeserializeHandler) { + handler.handle(this); + } else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.ParameterHandler) { + handler.handle(this); + } else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.InstanceHandler) { + handler.handle(this); + } else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.InvocationHandler) { + handler.handle(this); + } else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.FixedProducesHandler) { + handler.handle(this); + } else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.ResponseHandler) { + handler.handle(this); + } else if (handler instanceof org.jboss.resteasy.reactive.server.handlers.ResponseWriterHandler) { + handler.handle(this); + } else { + // megamorphic call for other handlers + handler.handle(this); + } + } } diff --git a/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/core/AbstractResteasyReactiveContext.java b/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/core/AbstractResteasyReactiveContext.java index e317078547df1..a0529d63f83b9 100644 --- a/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/core/AbstractResteasyReactiveContext.java +++ b/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/common/core/AbstractResteasyReactiveContext.java @@ -138,7 +138,7 @@ public void run() { int pos = position; position++; //increment before, as reset may reset it to zero try { - handlers[pos].handle((T) this); + invokeHandler(pos); if (suspended) { synchronized (this) { // as running is not volatile but instead read from inside the same monitor, @@ -215,6 +215,10 @@ public void run() { } } + protected void invokeHandler(int pos) throws Exception { + handlers[pos].handle((T) this); + } + protected void beginAsyncProcessing() { }