diff -r 7f676353195d -r 668b6d00cc79 jdk/src/java.desktop/share/classes/javax/swing/text/PlainView.java --- a/jdk/src/java.desktop/share/classes/javax/swing/text/PlainView.java Wed Dec 21 17:34:41 2016 +0300 +++ b/jdk/src/java.desktop/share/classes/javax/swing/text/PlainView.java Thu Dec 22 12:09:34 2016 +0300 @@ -32,6 +32,8 @@ import java.util.Objects; import javax.swing.event.*; import java.lang.reflect.Module; +import java.lang.ref.SoftReference; +import java.util.HashMap; /** * Implements View interface for a simple multi-line text view @@ -818,10 +820,45 @@ return w; } - static boolean isFPMethodOverriden(String method, - Class cls, - Class[] intTypes, - Class[] fpTypes) + static boolean getFPMethodOverridden(Class cls, String method, + FPMethodArgs methodArgs) { + HashMap map = null; + boolean initialized = methodsOverriddenMapRef != null + && (map = methodsOverriddenMapRef.get()) != null; + + if (!initialized) { + map = new HashMap<>(); + methodsOverriddenMapRef = new SoftReference<>(map); + } + + FPMethodItem key = new FPMethodItem(cls, method); + Boolean isFPMethodOverridden = map.get(key); + if (isFPMethodOverridden == null) { + isFPMethodOverridden = checkFPMethodOverridden(cls, method, methodArgs); + map.put(key, isFPMethodOverridden); + } + return isFPMethodOverridden; + } + + private static boolean checkFPMethodOverridden(final Class className, + final String methodName, + final FPMethodArgs methodArgs) { + + return AccessController + .doPrivileged(new PrivilegedAction() { + @Override + public Boolean run() { + return isFPMethodOverridden(methodName, className, + methodArgs.getMethodArguments(false), + methodArgs.getMethodArguments(true)); + } + }); + } + + private static boolean isFPMethodOverridden(String method, + Class cls, + Class[] intTypes, + Class[] fpTypes) { Module thisModule = PlainView.class.getModule(); while (!thisModule.equals(cls.getModule())) { @@ -840,6 +877,57 @@ return true; } + enum FPMethodArgs { + + IGNN, + IIGNN, + GNNII, + GNNC; + + public Class[] getMethodArguments(boolean isFPType) { + Class N = (isFPType) ? Float.TYPE : Integer.TYPE; + Class G = (isFPType) ? Graphics2D.class : Graphics.class; + switch (this) { + case IGNN: + return new Class[]{Integer.TYPE, G, N, N}; + case IIGNN: + return new Class[]{Integer.TYPE, Integer.TYPE, G, N, N}; + case GNNII: + return new Class[]{G, N, N, Integer.TYPE, Integer.TYPE}; + case GNNC: + return new Class[]{G, N, N, Character.TYPE}; + default: + throw new RuntimeException("Unknown method arguments!"); + } + } + } + + private static class FPMethodItem { + + final Class className; + final String methodName; + + public FPMethodItem(Class className, String methodName) { + this.className = className; + this.methodName = methodName; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof FPMethodItem) { + FPMethodItem that = (FPMethodItem) obj; + return this.className.equals(that.className) + && this.methodName.equals(that.methodName); + } + return false; + } + + @Override + public int hashCode() { + return 31 * methodName.hashCode() + className.hashCode(); + } + } + // --- member variables ----------------------------------------------- /** @@ -878,46 +966,13 @@ */ int firstLineOffset; - final boolean drawLineOverridden; - final boolean drawSelectedTextOverridden; - final boolean drawUnselectedTextOverridden; - final boolean useFloatingPointAPI; - - { - final Class CLS = getClass(); - final Class INT = Integer.TYPE; - final Class FP = Float.TYPE; - - drawLineOverridden = AccessController - .doPrivileged(new PrivilegedAction() { - @Override - public Boolean run() { - Class[] intTypes = {INT, Graphics.class, INT, INT}; - Class[] fpTypes = {INT, Graphics2D.class, FP, FP}; - return isFPMethodOverriden("drawLine", CLS, intTypes, fpTypes); - } - }); - - drawUnselectedTextOverridden = AccessController - .doPrivileged(new PrivilegedAction() { - @Override - public Boolean run() { - Class[] intTypes = {Graphics.class, INT, INT, INT, INT}; - Class[] fpTypes = {Graphics2D.class, FP, FP, INT, INT}; - return isFPMethodOverriden("drawUnselectedText", CLS, intTypes, fpTypes); - } - }); - - drawSelectedTextOverridden = AccessController - .doPrivileged(new PrivilegedAction() { - @Override - public Boolean run() { - Class[] intTypes = {Graphics.class, INT, INT, INT, INT}; - Class[] fpTypes = {Graphics2D.class, FP, FP, INT, INT}; - return isFPMethodOverriden("drawSelectedText", CLS, intTypes, fpTypes); - } - }); - - useFloatingPointAPI = drawUnselectedTextOverridden || drawSelectedTextOverridden; - } + private static SoftReference> methodsOverriddenMapRef; + final boolean drawLineOverridden = + getFPMethodOverridden(getClass(), "drawLine", FPMethodArgs.IGNN); + final boolean drawSelectedTextOverridden = + getFPMethodOverridden(getClass(), "drawSelectedText", FPMethodArgs.GNNII); + final boolean drawUnselectedTextOverridden = + getFPMethodOverridden(getClass(), "drawUnselectedText", FPMethodArgs.GNNII); + final boolean useFloatingPointAPI = + drawUnselectedTextOverridden || drawSelectedTextOverridden; }