src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java

changeset 1843
be62183f938a
parent 1824
455be95bd1b5
child 1882
39ec5d8a691b
equal deleted inserted replaced
1841:792c40d5185a 1843:be62183f938a
98 public static final int FLAG_SERIALIZABLE = 1 << 0; 98 public static final int FLAG_SERIALIZABLE = 1 << 0;
99 99
100 /** Flag for alternate metafactories indicating the lambda object has multiple targets */ 100 /** Flag for alternate metafactories indicating the lambda object has multiple targets */
101 public static final int FLAG_MARKERS = 1 << 1; 101 public static final int FLAG_MARKERS = 1 << 1;
102 102
103 /** Flag for alternate metafactories indicating the lambda object requires multiple bridges */
104 public static final int FLAG_BRIDGES = 1 << 2;
105
106 private class KlassInfo { 103 private class KlassInfo {
107 104
108 /** 105 /**
109 * list of methods to append 106 * list of methods to append
110 */ 107 */
322 319
323 //build a sam instance using an indy call to the meta-factory 320 //build a sam instance using an indy call to the meta-factory
324 int refKind = referenceKind(sym); 321 int refKind = referenceKind(sym);
325 322
326 //convert to an invokedynamic call 323 //convert to an invokedynamic call
327 result = makeMetaFactoryIndyCall(context, refKind, sym, indy_args); 324 result = makeMetaFactoryIndyCall(tree, context.needsAltMetafactory(), context.isSerializable(), refKind, sym, indy_args);
328 } 325 }
329 326
330 private JCIdent makeThis(Type type, Symbol owner) { 327 private JCIdent makeThis(Type type, Symbol owner) {
331 VarSymbol _this = new VarSymbol(PARAMETER | FINAL | SYNTHETIC, 328 VarSymbol _this = new VarSymbol(PARAMETER | FINAL | SYNTHETIC,
332 names._this, 329 names._this,
383 380
384 List<JCExpression> indy_args = init==null? List.<JCExpression>nil() : translate(List.of(init), localContext.prev); 381 List<JCExpression> indy_args = init==null? List.<JCExpression>nil() : translate(List.of(init), localContext.prev);
385 382
386 383
387 //build a sam instance using an indy call to the meta-factory 384 //build a sam instance using an indy call to the meta-factory
388 result = makeMetaFactoryIndyCall(localContext, localContext.referenceKind(), refSym, indy_args); 385 result = makeMetaFactoryIndyCall(tree, localContext.needsAltMetafactory(), localContext.isSerializable(), localContext.referenceKind(), refSym, indy_args);
389 } 386 }
390 387
391 /** 388 /**
392 * Translate identifiers within a lambda to the mapped identifier 389 * Translate identifiers within a lambda to the mapped identifier
393 * @param tree 390 * @param tree
909 } 906 }
910 907
911 /** 908 /**
912 * Generate an indy method call to the meta factory 909 * Generate an indy method call to the meta factory
913 */ 910 */
914 private JCExpression makeMetaFactoryIndyCall(TranslationContext<?> context, 911 private JCExpression makeMetaFactoryIndyCall(JCFunctionalExpression tree, boolean needsAltMetafactory,
915 int refKind, Symbol refSym, List<JCExpression> indy_args) { 912 boolean isSerializable, int refKind, Symbol refSym, List<JCExpression> indy_args) {
916 JCFunctionalExpression tree = context.tree;
917 //determine the static bsm args 913 //determine the static bsm args
918 Type mtype = types.erasure(tree.getDescriptorType(types)); 914 Type mtype = types.erasure(tree.descriptorType);
919 MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.type.tsym); 915 MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.type.tsym);
920 List<Object> staticArgs = List.<Object>of( 916 List<Object> staticArgs = List.<Object>of(
921 new Pool.MethodHandle(ClassFile.REF_invokeInterface, 917 new Pool.MethodHandle(ClassFile.REF_invokeInterface,
922 types.findDescriptorSymbol(tree.type.tsym), types), 918 types.findDescriptorSymbol(tree.type.tsym), types),
923 new Pool.MethodHandle(refKind, refSym, types), 919 new Pool.MethodHandle(refKind, refSym, types),
936 MethodType indyType = new MethodType(indy_args_types.toList(), 932 MethodType indyType = new MethodType(indy_args_types.toList(),
937 tree.type, 933 tree.type,
938 List.<Type>nil(), 934 List.<Type>nil(),
939 syms.methodClass); 935 syms.methodClass);
940 936
941 Name metafactoryName = context.needsAltMetafactory() ? 937 Name metafactoryName = needsAltMetafactory ?
942 names.altMetaFactory : names.metaFactory; 938 names.altMetaFactory : names.metaFactory;
943 939
944 if (context.needsAltMetafactory()) { 940 if (needsAltMetafactory) {
945 ListBuffer<Object> markers = ListBuffer.lb(); 941 ListBuffer<Object> markers = ListBuffer.lb();
946 for (Type t : tree.targets.tail) { 942 for (Symbol t : tree.targets.tail) {
947 if (t.tsym != syms.serializableType.tsym) { 943 if (t != syms.serializableType.tsym) {
948 markers.append(t.tsym); 944 markers.append(t);
949 } 945 }
950 } 946 }
951 int flags = context.isSerializable() ? FLAG_SERIALIZABLE : 0; 947 int flags = isSerializable? FLAG_SERIALIZABLE : 0;
952 boolean hasMarkers = markers.nonEmpty(); 948 boolean hasMarkers = markers.nonEmpty();
953 boolean hasBridges = context.bridges.nonEmpty(); 949 flags |= hasMarkers ? FLAG_MARKERS : 0;
954 if (hasMarkers) {
955 flags |= FLAG_MARKERS;
956 }
957 if (hasBridges) {
958 flags |= FLAG_BRIDGES;
959 }
960 staticArgs = staticArgs.append(flags); 950 staticArgs = staticArgs.append(flags);
961 if (hasMarkers) { 951 if (hasMarkers) {
962 staticArgs = staticArgs.append(markers.length()); 952 staticArgs = staticArgs.append(markers.length());
963 staticArgs = staticArgs.appendList(markers.toList()); 953 staticArgs = staticArgs.appendList(markers.toList());
964 } 954 }
965 if (hasBridges) { 955 if (isSerializable) {
966 staticArgs = staticArgs.append(context.bridges.length() - 1);
967 for (Symbol s : context.bridges) {
968 Type s_erasure = s.erasure(types);
969 if (!types.isSameType(s_erasure, samSym.erasure(types))) {
970 staticArgs = staticArgs.append(s.erasure(types));
971 }
972 }
973 }
974 if (context.isSerializable()) {
975 addDeserializationCase(refKind, refSym, tree.type, samSym, 956 addDeserializationCase(refKind, refSym, tree.type, samSym,
976 tree, staticArgs, indyType); 957 tree, staticArgs, indyType);
977 } 958 }
978 } 959 }
979 960
1316 JCNewClass nc = makeNewClass(classType, make.Idents(params)); 1297 JCNewClass nc = makeNewClass(classType, make.Idents(params));
1317 nc.pos = tree.pos; 1298 nc.pos = tree.pos;
1318 1299
1319 // Make lambda holding the new-class call 1300 // Make lambda holding the new-class call
1320 JCLambda slam = make.Lambda(params, nc); 1301 JCLambda slam = make.Lambda(params, nc);
1302 slam.descriptorType = tree.descriptorType;
1321 slam.targets = tree.targets; 1303 slam.targets = tree.targets;
1322 slam.type = tree.type; 1304 slam.type = tree.type;
1323 slam.pos = tree.pos; 1305 slam.pos = tree.pos;
1324 1306
1325 // Now it is a lambda, process as such 1307 // Now it is a lambda, process as such
1650 int depth; 1632 int depth;
1651 1633
1652 /** the enclosing translation context (set for nested lambdas/mref) */ 1634 /** the enclosing translation context (set for nested lambdas/mref) */
1653 TranslationContext<?> prev; 1635 TranslationContext<?> prev;
1654 1636
1655 /** list of methods to be bridged by the meta-factory */
1656 List<Symbol> bridges;
1657
1658 TranslationContext(T tree) { 1637 TranslationContext(T tree) {
1659 this.tree = tree; 1638 this.tree = tree;
1660 this.owner = owner(); 1639 this.owner = owner();
1661 this.depth = frameStack.size() - 1; 1640 this.depth = frameStack.size() - 1;
1662 this.prev = context(); 1641 this.prev = context();
1663 ClassSymbol csym =
1664 types.makeFunctionalInterfaceClass(attrEnv, names.empty, tree.targets, ABSTRACT | INTERFACE);
1665 this.bridges = types.functionalInterfaceBridges(csym);
1666 } 1642 }
1667 1643
1668 /** does this functional expression need to be created using alternate metafactory? */ 1644 /** does this functional expression need to be created using alternate metafactory? */
1669 boolean needsAltMetafactory() { 1645 boolean needsAltMetafactory() {
1670 return tree.targets.length() > 1 || 1646 return (tree.targets.length() > 1 ||
1671 isSerializable() || 1647 isSerializable());
1672 bridges.length() > 1;
1673 } 1648 }
1674 1649
1675 /** does this functional expression require serialization support? */ 1650 /** does this functional expression require serialization support? */
1676 boolean isSerializable() { 1651 boolean isSerializable() {
1677 for (Type target : tree.targets) { 1652 for (Symbol target : tree.targets) {
1678 if (types.asSuper(target, syms.serializableType.tsym) != null) { 1653 if (types.asSuper(target.type, syms.serializableType.tsym) != null) {
1679 return true; 1654 return true;
1680 } 1655 }
1681 } 1656 }
1682 return false; 1657 return false;
1683 } 1658 }
1856 generatedLambdaSig(), 1831 generatedLambdaSig(),
1857 TreeInfo.types(syntheticParams)); 1832 TreeInfo.types(syntheticParams));
1858 } 1833 }
1859 1834
1860 Type generatedLambdaSig() { 1835 Type generatedLambdaSig() {
1861 return types.erasure(tree.getDescriptorType(types)); 1836 return types.erasure(tree.descriptorType);
1862 } 1837 }
1863 } 1838 }
1864 1839
1865 /** 1840 /**
1866 * This class retains all the useful information about a method reference; 1841 * This class retains all the useful information about a method reference;
1932 Type generatedRefSig() { 1907 Type generatedRefSig() {
1933 return types.erasure(tree.sym.type); 1908 return types.erasure(tree.sym.type);
1934 } 1909 }
1935 1910
1936 Type bridgedRefSig() { 1911 Type bridgedRefSig() {
1937 return types.erasure(types.findDescriptorSymbol(tree.targets.head.tsym).type); 1912 return types.erasure(types.findDescriptorSymbol(tree.targets.head).type);
1938 } 1913 }
1939 } 1914 }
1940 } 1915 }
1941 // </editor-fold> 1916 // </editor-fold>
1942 1917

mercurial