4141 */
4242public final class Definition {
4343
44+ private static final Map <String , Method > methodCache = new HashMap <>();
45+ private static final Map <String , Field > fieldCache = new HashMap <>();
46+
4447 private static final Pattern TYPE_NAME_PATTERN = Pattern .compile ("^[_a-zA-Z][._a-zA-Z0-9]*$" );
4548
4649 public static final String [] DEFINITION_FILES = new String [] {
@@ -533,6 +536,22 @@ Collection<Type> allSimpleTypes() {
533536 return simpleTypesMap .values ();
534537 }
535538
539+ private static String buildMethodCacheKey (String structName , String methodName , List <Type > arguments ) {
540+ StringBuilder key = new StringBuilder ();
541+ key .append (structName );
542+ key .append (methodName );
543+
544+ for (Type argument : arguments ) {
545+ key .append (argument .name );
546+ }
547+
548+ return key .toString ();
549+ }
550+
551+ private static String buildFieldCacheKey (String structName , String fieldName , String typeName ) {
552+ return structName + fieldName + typeName ;
553+ }
554+
536555 // INTERNAL IMPLEMENTATION:
537556
538557 private final Map <Class <?>, RuntimeClass > runtimeMap ;
@@ -836,8 +855,10 @@ private void addConstructor(String ownerStructName, Whitelist.Constructor whitel
836855 " with constructor parameters " + whitelistConstructor .painlessParameterTypeNames );
837856 }
838857
839- painlessConstructor = new Method ("<init>" , ownerStruct , null , getTypeInternal ("void" ), painlessParametersTypes ,
840- asmConstructor , javaConstructor .getModifiers (), javaHandle );
858+ painlessConstructor = methodCache .computeIfAbsent (buildMethodCacheKey (ownerStruct .name , "<init>" , painlessParametersTypes ),
859+ key -> new Method ("<init>" , ownerStruct , null , getTypeInternal ("void" ), painlessParametersTypes ,
860+ asmConstructor , javaConstructor .getModifiers (), javaHandle ));
861+
841862 ownerStruct .constructors .put (painlessMethodKey , painlessConstructor );
842863 } else if (painlessConstructor .arguments .equals (painlessParametersTypes ) == false ){
843864 throw new IllegalArgumentException (
@@ -859,7 +880,7 @@ private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName,
859880 " [" + whitelistMethod .javaMethodName + "] for owner struct [" + ownerStructName + "]." );
860881 }
861882
862- Class <?> javaAugmentedClass = null ;
883+ Class <?> javaAugmentedClass ;
863884
864885 if (whitelistMethod .javaAugmentedClassName != null ) {
865886 try {
@@ -869,6 +890,8 @@ private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName,
869890 "not found for method with name [" + whitelistMethod .javaMethodName + "] " +
870891 "and parameters " + whitelistMethod .painlessParameterTypeNames , cnfe );
871892 }
893+ } else {
894+ javaAugmentedClass = null ;
872895 }
873896
874897 int augmentedOffset = javaAugmentedClass == null ? 0 : 1 ;
@@ -939,8 +962,10 @@ private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName,
939962 "[" + whitelistMethod .javaMethodName + "] and parameters " + whitelistMethod .painlessParameterTypeNames );
940963 }
941964
942- painlessMethod = new Method (whitelistMethod .javaMethodName , ownerStruct , null , painlessReturnType ,
943- painlessParametersTypes , asmMethod , javaMethod .getModifiers (), javaMethodHandle );
965+ painlessMethod = methodCache .computeIfAbsent (
966+ buildMethodCacheKey (ownerStruct .name , whitelistMethod .javaMethodName , painlessParametersTypes ),
967+ key -> new Method (whitelistMethod .javaMethodName , ownerStruct , null , painlessReturnType , painlessParametersTypes ,
968+ asmMethod , javaMethod .getModifiers (), javaMethodHandle ));
944969 ownerStruct .staticMethods .put (painlessMethodKey , painlessMethod );
945970 } else if ((painlessMethod .name .equals (whitelistMethod .javaMethodName ) && painlessMethod .rtn .equals (painlessReturnType ) &&
946971 painlessMethod .arguments .equals (painlessParametersTypes )) == false ) {
@@ -963,8 +988,10 @@ private void addMethod(ClassLoader whitelistClassLoader, String ownerStructName,
963988 "[" + whitelistMethod .javaMethodName + "] and parameters " + whitelistMethod .painlessParameterTypeNames );
964989 }
965990
966- painlessMethod = new Method (whitelistMethod .javaMethodName , ownerStruct , javaAugmentedClass , painlessReturnType ,
967- painlessParametersTypes , asmMethod , javaMethod .getModifiers (), javaMethodHandle );
991+ painlessMethod = methodCache .computeIfAbsent (
992+ buildMethodCacheKey (ownerStruct .name , whitelistMethod .javaMethodName , painlessParametersTypes ),
993+ key -> new Method (whitelistMethod .javaMethodName , ownerStruct , javaAugmentedClass , painlessReturnType ,
994+ painlessParametersTypes , asmMethod , javaMethod .getModifiers (), javaMethodHandle ));
968995 ownerStruct .methods .put (painlessMethodKey , painlessMethod );
969996 } else if ((painlessMethod .name .equals (whitelistMethod .javaMethodName ) && painlessMethod .rtn .equals (painlessReturnType ) &&
970997 painlessMethod .arguments .equals (painlessParametersTypes )) == false ) {
@@ -1016,33 +1043,40 @@ private void addField(String ownerStructName, Whitelist.Field whitelistField) {
10161043 Field painlessField = ownerStruct .staticMembers .get (whitelistField .javaFieldName );
10171044
10181045 if (painlessField == null ) {
1019- painlessField = new Field (whitelistField .javaFieldName , javaField .getName (),
1020- ownerStruct , painlessFieldType , javaField .getModifiers (), null , null );
1046+ painlessField = fieldCache .computeIfAbsent (
1047+ buildFieldCacheKey (ownerStruct .name , whitelistField .javaFieldName , painlessFieldType .name ),
1048+ key -> new Field (whitelistField .javaFieldName , javaField .getName (),
1049+ ownerStruct , painlessFieldType , javaField .getModifiers (), null , null ));
10211050 ownerStruct .staticMembers .put (whitelistField .javaFieldName , painlessField );
10221051 } else if (painlessField .type .equals (painlessFieldType ) == false ) {
10231052 throw new IllegalArgumentException ("illegal duplicate static fields [" + whitelistField .javaFieldName + "] " +
10241053 "found within the struct [" + ownerStruct .name + "] with type [" + whitelistField .painlessFieldTypeName + "]" );
10251054 }
10261055 } else {
1027- MethodHandle javaMethodHandleGetter = null ;
1028- MethodHandle javaMethodHandleSetter = null ;
1056+ MethodHandle javaMethodHandleGetter ;
1057+ MethodHandle javaMethodHandleSetter ;
10291058
10301059 try {
10311060 if (Modifier .isStatic (javaField .getModifiers ()) == false ) {
10321061 javaMethodHandleGetter = MethodHandles .publicLookup ().unreflectGetter (javaField );
10331062 javaMethodHandleSetter = MethodHandles .publicLookup ().unreflectSetter (javaField );
1063+ } else {
1064+ javaMethodHandleGetter = null ;
1065+ javaMethodHandleSetter = null ;
10341066 }
10351067 } catch (IllegalAccessException exception ) {
10361068 throw new IllegalArgumentException ("getter/setter [" + whitelistField .javaFieldName + "]" +
10371069 " not found for class [" + ownerStruct .clazz .getName () + "]." );
10381070 }
10391071
1040- Field painlessField = ownerStruct .staticMembers .get (whitelistField .javaFieldName );
1072+ Field painlessField = ownerStruct .members .get (whitelistField .javaFieldName );
10411073
10421074 if (painlessField == null ) {
1043- painlessField = new Field (whitelistField .javaFieldName , javaField .getName (),
1044- ownerStruct , painlessFieldType , javaField .getModifiers (), javaMethodHandleGetter , javaMethodHandleSetter );
1045- ownerStruct .staticMembers .put (whitelistField .javaFieldName , painlessField );
1075+ painlessField = fieldCache .computeIfAbsent (
1076+ buildFieldCacheKey (ownerStruct .name , whitelistField .javaFieldName , painlessFieldType .name ),
1077+ key -> new Field (whitelistField .javaFieldName , javaField .getName (),
1078+ ownerStruct , painlessFieldType , javaField .getModifiers (), javaMethodHandleGetter , javaMethodHandleSetter ));
1079+ ownerStruct .members .put (whitelistField .javaFieldName , painlessField );
10461080 } else if (painlessField .type .equals (painlessFieldType ) == false ) {
10471081 throw new IllegalArgumentException ("illegal duplicate member fields [" + whitelistField .javaFieldName + "] " +
10481082 "found within the struct [" + ownerStruct .name + "] with type [" + whitelistField .painlessFieldTypeName + "]" );
0 commit comments