Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8273914

Indy string concat changes order of operations

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: New
    • Priority: P4
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: tbd
    • Component/s: tools
    • Labels:
      None

      Description

      The invokedynamic string concatenation strategies don't preserve the order of operations when evaluating subexpressions and converting them to strings.

      With the inline strategy, each subexpression is evaluated and converted to a string in order. With indy each subexpression is evaluated in order *but not converted to a string*, and later each subexpression is converted to a string in order.

      Originally reported on compiler-dev@ [1]. briangoetz confirmed the original behaviour of the inline strategy [2] is correct, and sketched one possible fix [3]:

      > The nature of indy leads to the structure we ended up with. The natural
      > way to do this is to have the various arguments passed as real stack
      > arguments, causing them to all be evaluated before being pushed through
      > the MH nest (which is where the string conversion happens, using
      > MethodHandle::filterArguments.) We'd essentially have to write a new
      > bootstrap (but leave the old one in place), and have the compiler
      > generate bytecode to do the string conversion as the values are being
      > pushed on the stack. This requires a different bootstrap and a
      > different calling convention. So old bytecode will stay around, and the
      > old bootstrap would have to be kept around ... pretty disruptive.

      [1] https://mail.openjdk.java.net/pipermail/compiler-dev/2021-September/017911.html
      [2] https://mail.openjdk.java.net/pipermail/compiler-dev/2021-September/017912.html
      [3] https://mail.openjdk.java.net/pipermail/compiler-dev/2021-September/017929.html

      Repro:

      class T {
        static String test() {
          StringBuilder builder = new StringBuilder("foo");
          return "" + builder + builder.append("bar");
        }

        public static void main(String[] args) {
          System.err.println(test());
        }
      }

      $ javac -XDstringConcat=inline T.java ; java T
      foofoobar

      $ javac -XDstringConcat=indy T.java ; java T
      foobarfoobar

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              cushon Liam Miller-Cushon
              Reporter:
              cushon Liam Miller-Cushon
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Dates

                Created:
                Updated: