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