src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java
changeset 54791 04f603ebb6c2
parent 54652 1cb0306f16d1
equal deleted inserted replaced
54790:b77bf7f216f4 54791:04f603ebb6c2
  1664             // Coders are more interesting. Only Object, String and char arguments (and constants)
  1664             // Coders are more interesting. Only Object, String and char arguments (and constants)
  1665             // can have non-Latin1 encoding. It is easier to blindly convert constants to String,
  1665             // can have non-Latin1 encoding. It is easier to blindly convert constants to String,
  1666             // and deduce the coder from there. Arguments would be either converted to Strings
  1666             // and deduce the coder from there. Arguments would be either converted to Strings
  1667             // during the initial filtering, or handled by specializations in MIXERS.
  1667             // during the initial filtering, or handled by specializations in MIXERS.
  1668             //
  1668             //
  1669             // The method handle shape before and after all mixers are combined in is:
  1669             // The method handle shape before all mixers are combined in is:
  1670             //   (long, <args>)String = ("indexCoder", <args>)
  1670             //   (long, <args>)String = ("indexCoder", <args>)
  1671 
  1671             //
       
  1672             // We will bind the initialLengthCoder value to the last mixer (the one that will be
       
  1673             // executed first), then fold that in. This leaves the shape after all mixers are
       
  1674             // combined in as:
       
  1675             //   (<args>)String = (<args>)
       
  1676 
       
  1677             int ac = -1;
       
  1678             MethodHandle mix = null;
  1672             for (RecipeElement el : recipe.getElements()) {
  1679             for (RecipeElement el : recipe.getElements()) {
  1673                 switch (el.getTag()) {
  1680                 switch (el.getTag()) {
  1674                     case TAG_CONST:
  1681                     case TAG_CONST:
  1675                         // Constants already handled in the code above
  1682                         // Constants already handled in the code above
  1676                         break;
  1683                         break;
  1677                     case TAG_ARG:
  1684                     case TAG_ARG:
  1678                         int ac = el.getArgPos();
  1685                         if (ac >= 0) {
  1679 
  1686                             // Compute new "index" in-place using old value plus the appropriate argument.
       
  1687                             mh = MethodHandles.filterArgumentsWithCombiner(mh, 0, mix,
       
  1688                                     0, // old-index
       
  1689                                     1 + ac // selected argument
       
  1690                             );
       
  1691                         }
       
  1692 
       
  1693                         ac = el.getArgPos();
  1680                         Class<?> argClass = ptypes[ac];
  1694                         Class<?> argClass = ptypes[ac];
  1681                         MethodHandle mix = mixer(argClass);
  1695                         mix = mixer(argClass);
  1682 
       
  1683                         // Compute new "index" in-place using old value plus the appropriate argument.
       
  1684                         mh = MethodHandles.filterArgumentsWithCombiner(mh, 0, mix,
       
  1685                                 0, // old-index
       
  1686                                 1 + ac // selected argument
       
  1687                         );
       
  1688 
  1696 
  1689                         break;
  1697                         break;
  1690                     default:
  1698                     default:
  1691                         throw new StringConcatException("Unhandled tag: " + el.getTag());
  1699                         throw new StringConcatException("Unhandled tag: " + el.getTag());
  1692                 }
  1700                 }
  1693             }
  1701             }
  1694 
  1702 
  1695             // Insert initial length and coder value here.
  1703             // Insert the initialLengthCoder value into the final mixer, then
       
  1704             // fold that into the base method handle
       
  1705             if (ac >= 0) {
       
  1706                 mix = MethodHandles.insertArguments(mix, 0, initialLengthCoder);
       
  1707                 mh = MethodHandles.foldArgumentsWithCombiner(mh, 0, mix,
       
  1708                         1 + ac // selected argument
       
  1709                 );
       
  1710             } else {
       
  1711                 // No mixer (constants only concat), insert initialLengthCoder directly
       
  1712                 mh = MethodHandles.insertArguments(mh, 0, initialLengthCoder);
       
  1713             }
       
  1714 
  1696             // The method handle shape here is (<args>).
  1715             // The method handle shape here is (<args>).
  1697             mh = MethodHandles.insertArguments(mh, 0, initialLengthCoder);
       
  1698 
  1716 
  1699             // Apply filters, converting the arguments:
  1717             // Apply filters, converting the arguments:
  1700             if (filters != null) {
  1718             if (filters != null) {
  1701                 mh = MethodHandles.filterArguments(mh, 0, filters);
  1719                 mh = MethodHandles.filterArguments(mh, 0, filters);
  1702             }
  1720             }