OpenJDK / amber / amber
changeset 55381:abb07ff1dbe3 records-and-sealed
folding all bootstraps at ObjectMethodBuilders into one
author | vromero |
---|---|
date | Sat, 23 Mar 2019 20:59:47 -0400 |
parents | ee1dea3bfa8f |
children | e752ba81c19d |
files | src/java.base/share/classes/java/lang/invoke/ObjectMethodBuilders.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java |
diffstat | 4 files changed, 84 insertions(+), 139 deletions(-) [+] |
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/invoke/ObjectMethodBuilders.java Thu Mar 14 12:18:50 2019 -0400 +++ b/src/java.base/share/classes/java/lang/invoke/ObjectMethodBuilders.java Sat Mar 23 20:59:47 2019 -0400 @@ -235,48 +235,43 @@ } /** - * Bootstrap method to generate the {@code equals} method for a given data class - * @param lookup the lookup - * @param invName the name - * @param invType the method type - * @param dataClass the data class - * @param getters the list of getters - * @return a call site + * Bootstrap method to generate the {@code equals}, {@code hashCode}, and {@code toString} methods for a given data class + * @param lookup the lookup + * @param methodName the method name + * @param type the method type + * @param theClass the data class + * @param names the list of field names joined into a string, separated by ";" + * @param getters the list of getters + * @return a call site if invoked by and indy or a method handle if invoked by a condy * @throws Throwable if any exception is thrown during call site construction */ - public static CallSite makeEquals(MethodHandles.Lookup lookup, String invName, MethodType invType, - Class<?> dataClass, MethodHandle... getters) throws Throwable { - return new ConstantCallSite(makeEquals(dataClass, List.of(getters))); - } - - /** - * Bootstrap method to generate the {@code hashCode} method for a given data class - * @param lookup the lookup - * @param invName the name - * @param invType the method type - * @param dataClass the data class - * @param getters the list of getters - * @return a call site - * @throws Throwable if any exception is thrown during call site construction - */ - public static CallSite makeHashCode(MethodHandles.Lookup lookup, String invName, MethodType invType, - Class<?> dataClass, MethodHandle... getters) throws Throwable { - return new ConstantCallSite(makeHashCode(dataClass, List.of(getters))); - } - - /** - * Bootstrap method to generate the {@code toString} method for a given data class - * @param lookup the lookup - * @param invName the name - * @param invType the method type - * @param dataClass the data class - * @param names the list of field names joined into a string, separated by ";" - * @param getters the list of getters - * @return a call site - * @throws Throwable if any exception is thrown during call site construction - */ - public static CallSite makeToString(MethodHandles.Lookup lookup, String invName, MethodType invType, - Class<?> dataClass, String names, MethodHandle... getters) throws Throwable { - return new ConstantCallSite(makeToString(dataClass, List.of(getters), List.of(names.split(";")))); + public static Object bootstrap(MethodHandles.Lookup lookup, String methodName, TypeDescriptor type, + Class<?> theClass, String names, MethodHandle... getters) throws Throwable { + MethodType methodType; + if (type instanceof MethodType) + methodType = (MethodType) type; + else { + methodType = null; + if (!MethodHandle.class.equals(type)) + throw new IllegalArgumentException(type.toString()); + } + List<MethodHandle> getterList = List.of(getters); + MethodHandle handle; + switch (methodName) { + case "equals": + // validate method type + handle = makeEquals(theClass, getterList); + return methodType != null ? new ConstantCallSite(handle) : handle; + case "hashCode": + // validate method type + handle = makeHashCode(theClass, getterList); + return methodType != null ? new ConstantCallSite(handle) : handle; + case "toString": + // validate method type + handle = makeToString(theClass, getterList, List.of(names.split(";"))); + return methodType != null ? new ConstantCallSite(handle) : handle; + default: + throw new IllegalArgumentException(methodName); + } } }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java Thu Mar 14 12:18:50 2019 -0400 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java Sat Mar 23 20:59:47 2019 -0400 @@ -217,6 +217,7 @@ public final Type elementTypeType; public final Type functionalInterfaceType; public final Type extractorType; + public final Type typeDescriptorType; /** The symbol representing the length field of an array. */ @@ -575,6 +576,7 @@ stringConcatFactory = enterClass("java.lang.invoke.StringConcatFactory"); functionalInterfaceType = enterClass("java.lang.FunctionalInterface"); extractorType = enterClass("java.lang.compiler.Extractor"); + typeDescriptorType = enterClass("java.lang.invoke.TypeDescriptor"); synthesizeEmptyInterfaceIfMissing(autoCloseableType); synthesizeEmptyInterfaceIfMissing(cloneableType);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java Thu Mar 14 12:18:50 2019 -0400 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java Sat Mar 23 20:59:47 2019 -0400 @@ -2481,23 +2481,23 @@ tree.defs = tree.defs.appendList(accessors(tree)); tree.defs = tree.defs.appendList(List.of( - recordEquals(tree, getterMethHandles), - recordToString(tree, vars, getterMethHandles), - recordHashCode(tree, getterMethHandles), + generateRecordMethod(tree, names.toString, vars, getterMethHandles), + generateRecordMethod(tree, names.hashCode, vars, getterMethHandles), + generateRecordMethod(tree, names.equals, vars, getterMethHandles), recordExtractor(tree, getterMethHandles), recordReadResolve(tree) )); } - JCTree recordToString(JCClassDecl tree, List<VarSymbol> vars, Pool.MethodHandle[] getterMethHandles) { + JCTree generateRecordMethod(JCClassDecl tree, Name name, List<VarSymbol> vars, Pool.MethodHandle[] getterMethHandles) { make_at(tree.pos()); - + boolean isEquals = name == names.equals; MethodSymbol msym = lookupMethod(tree.pos(), - names.toString, - tree.sym.type, - List.nil()); + name, + tree.sym.type, + isEquals ? List.of(syms.objectType) : List.nil()); if ((msym.flags() & RECORD) != 0) { - Name bootstrapName = names.makeToString; + Name bootstrapName = names.bootstrap; Object[] staticArgsValues = new Object[2 + getterMethHandles.length]; staticArgsValues[0] = tree.sym; String concatNames = vars.stream() @@ -2514,46 +2514,22 @@ syms.stringType, new ArrayType(syms.methodHandleType, syms.arrayClass)); - JCFieldAccess qualifier = makeIndyQualifier(syms.objectMethodBuildersType, - tree, msym, staticArgTypes, staticArgsValues, bootstrapName, false); + JCFieldAccess qualifier = makeIndyQualifier(syms.objectMethodBuildersType, tree, msym, + List.of(syms.methodHandleLookupType, + syms.stringType, + syms.typeDescriptorType).appendList(staticArgTypes), + staticArgsValues, bootstrapName, name, false); VarSymbol _this = new VarSymbol(SYNTHETIC, names._this, tree.sym.type, tree.sym); - JCMethodInvocation proxyCall = make.Apply(List.nil(), qualifier, List.of(make.Ident(_this))); - proxyCall.type = qualifier.type; - return make.MethodDef(msym, make.Block(0, List.of(make.Return(proxyCall)))); - } else { - return make.Block(SYNTHETIC, List.nil()); - } - } - - JCTree recordHashCode(JCClassDecl tree, Pool.MethodHandle[] getterMethHandles) { - make_at(tree.pos()); - MethodSymbol msym = lookupMethod(tree.pos(), - names.hashCode, - tree.sym.type, - List.nil()); - if ((msym.flags() & RECORD) != 0) { - Name bootstrapName = names.makeHashCode; - Object[] staticArgsValues = new Object[1 + getterMethHandles.length]; - staticArgsValues[0] = tree.sym; - int index = 1; - for (Object mho : getterMethHandles) { - staticArgsValues[index] = mho; - index++; + JCMethodInvocation proxyCall; + if (!isEquals) { + proxyCall = make.Apply(List.nil(), qualifier, List.of(make.Ident(_this))); + } else { + VarSymbol o = msym.params.head; + o.adr = 0; + proxyCall = make.Apply(List.nil(), qualifier, List.of(make.Ident(_this), make.Ident(o))); } - - List<Type> staticArgTypes = List.of(syms.classType, - new ArrayType(syms.methodHandleType, syms.arrayClass)); - - JCFieldAccess qualifier = makeIndyQualifier( - syms.objectMethodBuildersType, tree, msym, - staticArgTypes, staticArgsValues, bootstrapName, - false); - - VarSymbol _this = new VarSymbol(SYNTHETIC, names._this, tree.sym.type, tree.sym); - - JCMethodInvocation proxyCall = make.Apply(List.nil(), qualifier, List.of(make.Ident(_this))); proxyCall.type = qualifier.type; return make.MethodDef(msym, make.Block(0, List.of(make.Return(proxyCall)))); } else { @@ -2589,9 +2565,11 @@ List<Type> staticArgTypes = List.of(syms.methodTypeType, new ArrayType(syms.methodHandleType, syms.arrayClass)); - JCFieldAccess qualifier = makeIndyQualifier( - syms.extractorType, tree, extractorSym, staticArgTypes, - staticArgsValues, bootstrapName, true); + JCFieldAccess qualifier = makeIndyQualifier(syms.extractorType, tree, extractorSym, + List.of(syms.methodHandleLookupType, + syms.stringType, + syms.methodTypeType).appendList(staticArgTypes), + staticArgsValues, bootstrapName, bootstrapName, true); JCMethodInvocation proxyCall = make.Apply(List.nil(), qualifier, List.nil()); proxyCall.type = qualifier.type; @@ -2656,42 +2634,19 @@ } } - JCTree recordEquals(JCClassDecl tree, Pool.MethodHandle[] getterMethHandles) { - make_at(tree.pos()); - MethodSymbol msym = lookupMethod(tree.pos(), - names.equals, - tree.sym.type, - List.of(syms.objectType)); - - if ((msym.flags() & RECORD) != 0) { - Name bootstrapName = names.makeEquals; - Object[] staticArgsValues = new Object[1 + getterMethHandles.length]; - staticArgsValues[0] = tree.sym; - int index = 1; - for (Object mho : getterMethHandles) { - staticArgsValues[index] = mho; - index++; - } - - List<Type> staticArgTypes = List.of(syms.classType, - new ArrayType(syms.methodHandleType, syms.arrayClass)); - - JCFieldAccess qualifier = makeIndyQualifier( - syms.objectMethodBuildersType, tree, msym, - staticArgTypes, staticArgsValues, bootstrapName, false); - - VarSymbol o = msym.params.head; - o.adr = 0; - VarSymbol _this = new VarSymbol(SYNTHETIC, names._this, tree.sym.type, tree.sym); - - JCMethodInvocation proxyCall = make.Apply(List.nil(), qualifier, List.of(make.Ident(_this), make.Ident(o))); - proxyCall.type = qualifier.type; - return make.MethodDef(msym, make.Block(0, List.of(make.Return(proxyCall)))); - } else { - return make.Block(SYNTHETIC, List.nil()); - } - } - + /** + * Creates an indy qualifier, helpful to be part of an indy invocation + * @param site the site + * @param tree a class declaration tree + * @param msym the method symbol + * @param staticArgTypes the static argument types + * @param staticArgValues the static argument values + * @param bootstrapName the bootstrap name to look for + * @param argName normally bootstraps receives a method name as second argument, if you want that name + * to be different to that of the bootstrap name pass a different name here + * @param isStatic is it static or not + * @return a field access tree + */ JCFieldAccess makeIndyQualifier( Type site, JCClassDecl tree, @@ -2699,13 +2654,10 @@ List<Type> staticArgTypes, Object[] staticArgValues, Name bootstrapName, + Name argName, boolean isStatic) { - List<Type> bsm_staticArgs = List.of(syms.methodHandleLookupType, - syms.stringType, - syms.methodTypeType).appendList(staticArgTypes); - Symbol bsm = rs.resolveInternalMethod(tree.pos(), attrEnv, site, - bootstrapName, bsm_staticArgs, List.nil()); + bootstrapName, staticArgTypes, List.nil()); MethodType indyType = msym.type.asMethodType(); indyType = new MethodType( @@ -2714,13 +2666,13 @@ indyType.thrown, syms.methodClass ); - DynamicMethodSymbol dynSym = new DynamicMethodSymbol(bootstrapName, + DynamicMethodSymbol dynSym = new DynamicMethodSymbol(argName, syms.noSymbol, ClassFile.REF_invokeStatic, (MethodSymbol)bsm, indyType, staticArgValues); - JCFieldAccess qualifier = make.Select(make.QualIdent(site.tsym), bootstrapName); + JCFieldAccess qualifier = make.Select(make.QualIdent(site.tsym), argName); qualifier.sym = dynSym; qualifier.type = msym.type.asMethodType().restype; return qualifier;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java Thu Mar 14 12:18:50 2019 -0400 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java Sat Mar 23 20:59:47 2019 -0400 @@ -212,12 +212,10 @@ public final Name makeConcat; public final Name makeConcatWithConstants; + // record related // members of java.lang.invoke.ObjectMethodBuilders - public final Name makeEquals; - public final Name makeHashCode; - public final Name makeToString; + public final Name bootstrap; - // record related public final Name record; public final Name where; public final Name non; @@ -398,9 +396,7 @@ makeConcat = fromString("makeConcat"); makeConcatWithConstants = fromString("makeConcatWithConstants"); - makeEquals = fromString("makeEquals"); - makeHashCode = fromString("makeHashCode"); - makeToString = fromString("makeToString"); + bootstrap = fromString("bootstrap"); record = fromString("record"); where = fromString("where"); non = fromString("non");