You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2023/11/27 14:09:30 UTC
(tomcat) 04/04: Fix BZ 68119 - Refactor for improved performance during type conversion
This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit c466ebba66e6d51552b9d83004222e65c463cf2b
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Mon Nov 27 14:01:49 2023 +0000
Fix BZ 68119 - Refactor for improved performance during type conversion
https://bz.apache.org/bugzilla/show_bug.cgi?id=68119
---
java/jakarta/el/CompositeELResolver.java | 47 ++++++++++++++++++++++++++++++--
webapps/docs/changelog.xml | 8 ++++++
2 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/java/jakarta/el/CompositeELResolver.java b/java/jakarta/el/CompositeELResolver.java
index 401c898356..6844400f9f 100644
--- a/java/jakarta/el/CompositeELResolver.java
+++ b/java/jakarta/el/CompositeELResolver.java
@@ -17,13 +17,16 @@
package jakarta.el;
import java.beans.FeatureDescriptor;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Objects;
+import java.util.Set;
public class CompositeELResolver extends ELResolver {
private static final Class<?> SCOPED_ATTRIBUTE_EL_RESOLVER;
+ private static final Set<String> KNOWN_NON_TYPE_CONVERTING_RESOLVERS = new HashSet<>();
static {
Class<?> clazz = null;
try {
@@ -32,15 +35,41 @@ public class CompositeELResolver extends ELResolver {
// Ignore. This is expected if using the EL stand-alone
}
SCOPED_ATTRIBUTE_EL_RESOLVER = clazz;
+
+ // EL API Resolvers
+ KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add(ArrayELResolver.class.getName());
+ KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add(BeanELResolver.class.getName());
+ KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add(BeanNameELResolver.class.getName());
+ KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add(ListELResolver.class.getName());
+ KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add(MapELResolver.class.getName());
+ KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add(ResourceBundleELResolver.class.getName());
+ KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add(StaticFieldELResolver.class.getName());
+ // JSP API Resolvers - referenced by name to avoid creating dependency
+ KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add("jakarta.servlet.jsp.el.ImplicitObjectELResolver");
+ KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add("jakarta.servlet.jsp.el.ImportELResolver");
+ KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add("jakarta.servlet.jsp.el.NotFoundELResolver");
+ KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add("jakarta.servlet.jsp.el.ScopedAttributeELResolver");
+ // Tomcat internal resolvers - referenced by name to avoid creating dependency
+ KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add("org.apache.jasper.el.JasperELResolver");
+ KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add("org.apache.el.stream.StreamELResolverImpl");
}
private int resolversSize;
-
private ELResolver[] resolvers;
+ /*
+ * Use a separate array for ELResolvers that might implement type conversion as a performance optimisation. See
+ * https://bz.apache.org/bugzilla/show_bug.cgi?id=68119
+ */
+ private int typeConvertersSize;
+ private ELResolver[] typeConverters;
+
public CompositeELResolver() {
resolversSize = 0;
resolvers = new ELResolver[8];
+
+ typeConvertersSize = 0;
+ typeConverters = new ELResolver[0];
}
public void add(ELResolver elResolver) {
@@ -56,6 +85,20 @@ public class CompositeELResolver extends ELResolver {
resolvers = nr;
}
resolvers[resolversSize++] = elResolver;
+
+ if (KNOWN_NON_TYPE_CONVERTING_RESOLVERS.contains(elResolver.getClass().getName())) {
+ // Performance optimisation. ELResolver known not to perform type conversion
+ return;
+ }
+
+ if (typeConvertersSize == 0) {
+ typeConverters = new ELResolver[1];
+ } else if (typeConvertersSize == typeConverters.length) {
+ ELResolver[] expandedTypeConverters = new ELResolver[typeConvertersSize * 2];
+ System.arraycopy(typeConverters, 0, expandedTypeConverters, 0, typeConvertersSize);
+ typeConverters = expandedTypeConverters;
+ }
+ typeConverters[typeConvertersSize++] = elResolver;
}
@Override
@@ -154,7 +197,7 @@ public class CompositeELResolver extends ELResolver {
@Override
public <T> T convertToType(ELContext context, Object obj, Class<T> type) {
context.setPropertyResolved(false);
- int sz = this.resolversSize;
+ int sz = typeConvertersSize;
for (int i = 0; i < sz; i++) {
T result = this.resolvers[i].convertToType(context, obj, type);
if (context.isPropertyResolved()) {
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 93e5bba5d0..3f8c04bad5 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -113,6 +113,14 @@
</fix>
</changelog>
</subsection>
+ <subsection name="Jasper">
+ <changelog>
+ <scode>
+ <bug>68119</bug>: Refactor the <code>CompositeELResolver</code> to
+ improve performance during type conversion operations. (markt)
+ </scode>
+ </changelog>
+ </subsection>
<subsection name="Other">
<changelog>
<fix>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org